Vue組件懶加載的操作代碼
在當(dāng)今快節(jié)奏的數(shù)字世界中,網(wǎng)站性能對于吸引用戶和取得成功至關(guān)重要。然而,對于像首頁這樣的頁面,在不影響功能的前提下優(yōu)化性能就成了一項挑戰(zhàn)。
這就是 Vue 組件懶加載的用武之地。通過將非必要元素的加載推遲到可見時進行,開發(fā)人員可以增強用戶體驗,同時確保登陸頁面的快速加載。
懶加載是一種優(yōu)先加載關(guān)鍵內(nèi)容,同時推遲加載次要元素的技術(shù)。這種方法不僅能縮短頁面的初始加載時間,還能節(jié)約網(wǎng)絡(luò)資源,從而使用戶界面更輕量、反應(yīng)更靈敏。
在本文中,我將向你展示一種簡單的機制,使用 Intersection Observer API 在 Vue 組件可見時對其進行懶加載。
Intersection Observer API
Intersection Observer API 是一種功能強大的工具,它允許開發(fā)人員有效地跟蹤和響應(yīng)瀏覽器視口中元素可見性的變化。
它提供了一種異步觀察元素與其父元素之間或元素與視口之間交集的方法。它為檢測元素何時可見或隱藏提供了性能優(yōu)越的優(yōu)化解決方案,減少了對低效滾動事件監(jiān)聽器的需求,使開發(fā)人員能夠在必要時有選擇地加載或操作內(nèi)容,從而增強用戶體驗。
它通常用于實現(xiàn)諸如無限滾動和圖片懶加載等功能。
異步組件
Vue 3 提供了 defineAsyncComponent,用于僅在需要時異步加載組件。
它返回一個組件定義的 Promise:
import { defineAsyncComponent } from 'vue' const AsyncComp = defineAsyncComponent(() => { return new Promise((resolve, reject) => { // ...load component from server resolve(/* loaded component */) }) })
還可以處理錯誤和加載狀態(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)組件可見時,我們將使用該功能異步加載組件。
懶加載組件
現(xiàn)在,讓我們結(jié)合 Intersection Observer API 和 defineAsyncComponent
函數(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)建一個 lazyLoadComponentIfVisible
函數(shù),該函數(shù)接受以下參數(shù):
componentLoader
:返回一個解析為組件定義的 Promise 的函數(shù)loadingComponent
:異步組件加載時使用的組件。errorComponent
:加載失敗時使用的組件。delay
:顯示加載組件前的延遲。默認(rèn)值:200 毫秒。timeout
:如果提供了超時時間,則將顯示錯誤組件。默認(rèn)值:Infinity
。
函數(shù)返回 defineAsyncComponent
,其中包含在組件可見時異步加載組件的邏輯。
主要邏輯發(fā)生在 defineAsyncComponent
內(nèi)部的 loadingComponent
中:
我們使用 defineComponent
創(chuàng)建一個新組件,該組件包含一個渲染函數(shù),用于在傳遞給 lazyLoadComponentIfVisible
的 div
中渲染 loadingComponent
。該渲染函數(shù)包含一個指向加載組件根元素的模板ref
。
在 onMounted
中,我們會檢查 IntersectionObserver
是否受支持。如果不支持,我們將立即加載組件。否則,我們將創(chuàng)建一個 IntersectionObserver
,用于觀察已加載組件的根元素,以檢測它何時變得可見。當(dāng)組件變?yōu)榭梢姇r,我們會清理觀察者并加載組件。
現(xiàn)在,你可以使用該函數(shù)在組件可見時對其進行懶加載:
<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 組件可見時對其進行懶加載。如果有一個包含許多組件的首頁,并希望改善應(yīng)用程序的初始加載時間,這將非常有用。
到此這篇關(guān)于Vue組件懶加載的文章就介紹到這了,更多相關(guān)Vue組件懶加載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
從0到1搭建element后臺框架優(yōu)化篇(打包優(yōu)化)
這篇文章主要介紹了從0到1搭建element后臺框架優(yōu)化篇(打包優(yōu)化),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-05-05vue實現(xiàn)下拉多選、可搜索、全選功能(示例代碼)
本文介紹了如何在Vue中實現(xiàn)一個樹形結(jié)構(gòu)的下拉多選組件,支持任意一級選項的選擇,全選功能,以及搜索功能,通過在mounted生命周期中獲取數(shù)據(jù),并使用handleTree函數(shù)將接口返回的數(shù)據(jù)整理成樹形結(jié)構(gòu),實現(xiàn)了這一功能,感興趣的朋友一起看看吧2025-01-01使用vue-route 的 beforeEach 實現(xiàn)導(dǎo)航守衛(wèi)(路由跳轉(zhuǎn)前驗證登錄)功能
在網(wǎng)站中普遍會遇到這樣的需求,路由跳轉(zhuǎn)前做一些驗證,比如登錄驗證(未登錄去登錄頁)。下面腳本之家小編給大家?guī)砹耸褂胿ue-route 的 beforeEach 實現(xiàn)導(dǎo)航守衛(wèi)(路由跳轉(zhuǎn)前驗證登錄)功能,感興趣的朋友一起看看吧2018-03-03Vue3中的createGlobalState用法及示例詳解
createGlobalState 是 Vue 3 中一種管理全局狀態(tài)的簡便方式,通常用于管理多個組件間共享的狀態(tài),由 @vueuse/core 提供的,允許創(chuàng)建一個響應(yīng)式的全局狀態(tài),本文給大家介紹了Vue3中的createGlobalState用法及示例,需要的朋友可以參考下2024-10-10詳解vue 中使用 AJAX獲取數(shù)據(jù)的方法
本篇文章主要介紹了詳解vue 中使用 AJAX獲取數(shù)據(jù)的方法,在VUE開發(fā)時,數(shù)據(jù)可以使用jquery和vue-resource來獲取數(shù)據(jù),有興趣的可以了解一下。2017-01-01