Vue組件懶加載的操作代碼
在當(dāng)今快節(jié)奏的數(shù)字世界中,網(wǎng)站性能對于吸引用戶和取得成功至關(guān)重要。然而,對于像首頁這樣的頁面,在不影響功能的前提下優(yōu)化性能就成了一項(xiàng)挑戰(zhàn)。
這就是 Vue 組件懶加載的用武之地。通過將非必要元素的加載推遲到可見時(shí)進(jìn)行,開發(fā)人員可以增強(qiáng)用戶體驗(yàn),同時(shí)確保登陸頁面的快速加載。
懶加載是一種優(yōu)先加載關(guān)鍵內(nèi)容,同時(shí)推遲加載次要元素的技術(shù)。這種方法不僅能縮短頁面的初始加載時(shí)間,還能節(jié)約網(wǎng)絡(luò)資源,從而使用戶界面更輕量、反應(yīng)更靈敏。
在本文中,我將向你展示一種簡單的機(jī)制,使用 Intersection Observer API 在 Vue 組件可見時(shí)對其進(jìn)行懶加載。
Intersection Observer API
Intersection Observer API 是一種功能強(qiáng)大的工具,它允許開發(fā)人員有效地跟蹤和響應(yīng)瀏覽器視口中元素可見性的變化。
它提供了一種異步觀察元素與其父元素之間或元素與視口之間交集的方法。它為檢測元素何時(shí)可見或隱藏提供了性能優(yōu)越的優(yōu)化解決方案,減少了對低效滾動(dòng)事件監(jiān)聽器的需求,使開發(fā)人員能夠在必要時(shí)有選擇地加載或操作內(nèi)容,從而增強(qiáng)用戶體驗(yàn)。
它通常用于實(shí)現(xiàn)諸如無限滾動(dòng)和圖片懶加載等功能。
異步組件
Vue 3 提供了 defineAsyncComponent,用于僅在需要時(shí)異步加載組件。
它返回一個(gè)組件定義的 Promise:
import { defineAsyncComponent } from 'vue'
const AsyncComp = defineAsyncComponent(() => {
return new Promise((resolve, reject) => {
// ...load component from server
resolve(/* loaded component */)
})
})還可以處理錯(cuò)誤和加載狀態(tài):
const AsyncComp = defineAsyncComponent({
// the loader function
loader: () => import('./Foo.vue'),
// A component to use while the async component is loading
loadingComponent: LoadingComponent,
// Delay before showing the loading component. Default: 200ms.
delay: 200,
// A component to use if the load fails
errorComponent: ErrorComponent,
// The error component will be displayed if a timeout is
// provided and exceeded. Default: Infinity.
timeout: 3000
})當(dāng)組件可見時(shí),我們將使用該功能異步加載組件。
懶加載組件
現(xiàn)在,讓我們結(jié)合 Intersection Observer API 和 defineAsyncComponent 函數(shù),在組件可見時(shí)異步加載它們:
import {
h,
defineAsyncComponent,
defineComponent,
ref,
onMounted,
AsyncComponentLoader,
Component,
} from 'vue';
type ComponentResolver = (component: Component) => void
export const lazyLoadComponentIfVisible = ({
componentLoader,
loadingComponent,
errorComponent,
delay,
timeout
}: {
componentLoader: AsyncComponentLoader;
loadingComponent: Component;
errorComponent?: Component;
delay?: number;
timeout?: number;
}) => {
let resolveComponent: ComponentResolver;
return defineAsyncComponent({
// the loader function
loader: () => {
return new Promise((resolve) => {
// We assign the resolve function to a variable
// that we can call later inside the loadingComponent
// when the component becomes visible
resolveComponent = resolve as ComponentResolver;
});
},
// A component to use while the async component is loading
loadingComponent: defineComponent({
setup() {
// We create a ref to the root element of
// the loading component
const elRef = ref();
async function loadComponent() {
// `resolveComponent()` receives the
// the result of the dynamic `import()`
// that is returned from `componentLoader()`
const component = await componentLoader()
resolveComponent(component)
}
onMounted(async() => {
// We immediately load the component if
// IntersectionObserver is not supported
if (!('IntersectionObserver' in window)) {
await loadComponent();
return;
}
const observer = new IntersectionObserver((entries) => {
if (!entries[0].isIntersecting) {
return;
}
// We cleanup the observer when the
// component is not visible anymore
observer.unobserve(elRef.value);
await loadComponent();
});
// We observe the root of the
// mounted loading component to detect
// when it becomes visible
observer.observe(elRef.value);
});
return () => {
return h('div', { ref: elRef }, loadingComponent);
};
},
}),
// Delay before showing the loading component. Default: 200ms.
delay,
// A component to use if the load fails
errorComponent,
// The error component will be displayed if a timeout is
// provided and exceeded. Default: Infinity.
timeout,
});
};讓我們分解一下上面的代碼:
我們創(chuàng)建一個(gè) lazyLoadComponentIfVisible 函數(shù),該函數(shù)接受以下參數(shù):
componentLoader:返回一個(gè)解析為組件定義的 Promise 的函數(shù)loadingComponent:異步組件加載時(shí)使用的組件。errorComponent:加載失敗時(shí)使用的組件。delay:顯示加載組件前的延遲。默認(rèn)值:200 毫秒。timeout:如果提供了超時(shí)時(shí)間,則將顯示錯(cuò)誤組件。默認(rèn)值:Infinity。
函數(shù)返回 defineAsyncComponent,其中包含在組件可見時(shí)異步加載組件的邏輯。
主要邏輯發(fā)生在 defineAsyncComponent 內(nèi)部的 loadingComponent 中:
我們使用 defineComponent 創(chuàng)建一個(gè)新組件,該組件包含一個(gè)渲染函數(shù),用于在傳遞給 lazyLoadComponentIfVisible 的 div中渲染 loadingComponent。該渲染函數(shù)包含一個(gè)指向加載組件根元素的模板ref。
在 onMounted 中,我們會(huì)檢查 IntersectionObserver 是否受支持。如果不支持,我們將立即加載組件。否則,我們將創(chuàng)建一個(gè) IntersectionObserver,用于觀察已加載組件的根元素,以檢測它何時(shí)變得可見。當(dāng)組件變?yōu)榭梢姇r(shí),我們會(huì)清理觀察者并加載組件。
現(xiàn)在,你可以使用該函數(shù)在組件可見時(shí)對其進(jìn)行懶加載:
<script setup lang="ts">
import Loading from './components/Loading.vue';
import { lazyLoadComponentIfVisible } from './utils';
const LazyLoaded = lazyLoadComponentIfVisible({
componentLoader: () => import('./components/HelloWorld.vue'),
loadingComponent: Loading,
});
</script>
<template>
<LazyLoaded />
</template>總結(jié)
在本文中,我們學(xué)習(xí)了如何使用 Intersection Observer API 和 defineAsyncComponent 函數(shù)在 Vue 組件可見時(shí)對其進(jìn)行懶加載。如果有一個(gè)包含許多組件的首頁,并希望改善應(yīng)用程序的初始加載時(shí)間,這將非常有用。
到此這篇關(guān)于Vue組件懶加載的文章就介紹到這了,更多相關(guān)Vue組件懶加載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue3.0搭配.net core實(shí)現(xiàn)文件上傳組件
這篇文章主要介紹了vue3.0搭配.net core實(shí)現(xiàn)文件上傳組件,幫助大家開發(fā)Web應(yīng)用程序,完成需求,感興趣的朋友可以了解下2020-10-10
超詳細(xì)教程實(shí)現(xiàn)Vue底部導(dǎo)航欄TabBar
本文詳細(xì)講解了Vue實(shí)現(xiàn)TabBar底部導(dǎo)航欄的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-11-11
vue中手機(jī)號,郵箱正則驗(yàn)證以及60s發(fā)送驗(yàn)證碼的實(shí)例
下面小編就為大家分享一篇vue中手機(jī)號,郵箱正則驗(yàn)證以及60s發(fā)送驗(yàn)證碼的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03
vue采用EventBus實(shí)現(xiàn)跨組件通信及注意事項(xiàng)小結(jié)
EventBus是一種發(fā)布/訂閱事件設(shè)計(jì)模式的實(shí)踐。這篇文章主要介紹了vue采用EventBus實(shí)現(xiàn)跨組件通信及注意事項(xiàng),需要的朋友可以參考下2018-06-06
element中TimePicker時(shí)間選擇器禁用部分時(shí)間(顯示禁用到分鐘)
這篇文章主要介紹了element中TimePicker時(shí)間選擇器禁用部分時(shí)間(顯示禁用到分鐘),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03

