<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          社區(qū)精選|Vue 組件懶加載

          共 8013字,需瀏覽 17分鐘

           ·

          2023-09-26 22:40

          今天小編為大家?guī)淼氖巧鐓^(qū)作者 chuck 的文章,讓我們一起來學(xué)習(xí) Vue 組件懶加載。


          本文系翻譯,閱讀原文:https://mokkapps.de/blog/lazy-load-vue-component-when-it-becomes-visible




          在當(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)化解決方案,減少了對低效滾動事件監(jiān)聽器的需求,使開發(fā)人員能夠在必要時(shí)有選擇地加載或操作內(nèi)容,從而增強(qiáng)用戶體驗(yàn)。
          它通常用于實(shí)現(xiàn)諸如無限滾動和圖片懶加載等功能。


          異步組件

          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 中,我們會檢查 IntersectionObserver 是否受支持。如果不支持,我們將立即加載組件。否則,我們將創(chuàng)建一個(gè) IntersectionObserver,用于觀察已加載組件的根元素,以檢測它何時(shí)變得可見。當(dāng)組件變?yōu)榭梢姇r(shí),我們會清理觀察者并加載組件。

          現(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í)間,這將非常有用。




          點(diǎn)擊左下角閱讀原文,到 SegmentFault 思否社區(qū) 和文章作者展開更多互動和交流,公眾號后臺回復(fù)“ 入群 ”即可加入我們的技術(shù)交流群,收獲更多的技術(shù)文章~


          - END -



          往期推薦


          社區(qū)精選|Vue 3 中依賴注入與組件定義相關(guān)的那點(diǎn)事兒


          社區(qū)精選|瀏覽器要原生實(shí)現(xiàn) React 的并發(fā)更新了?


          社區(qū)精選|談?wù)?H5 移動端適配原理



          瀏覽 356
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日本黄色A V | 久久免费视频,久久免费视频 | 淫交黑料吃瓜AV | 日韩天堂在线 | 亚洲黄片在线免费看 |