亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Vue項(xiàng)目首屏性能優(yōu)化組件實(shí)戰(zhàn)指南

 更新時(shí)間:2021年11月09日 12:12:03   作者:WindrunnerMax  
Vue眾所周知是一個(gè)輕量級(jí)的框架,源碼僅僅為72.9KB,但是也有它自己的缺點(diǎn),就是首屏加載會(huì)比較慢,這篇文章主要給大家介紹了關(guān)于Vue項(xiàng)目首屏性能優(yōu)化組件的相關(guān)資料,需要的朋友可以參考下

Vue首屏性能優(yōu)化組件

簡(jiǎn)單實(shí)現(xiàn)一個(gè)Vue首屏性能優(yōu)化組件,現(xiàn)代化瀏覽器提供了很多新接口,在不考慮IE兼容性的情況下,這些接口可以很大程度上減少編寫(xiě)代碼的工作量以及做一些性能優(yōu)化方面的事情,當(dāng)然為了考慮IE我們也可以在封裝組件的時(shí)候?yàn)槠涠档?,本文的首屏性能?yōu)化組件主要是使用IntersectionObserver以及requestIdleCallback兩個(gè)接口。

描述

先考慮首屏場(chǎng)景,當(dāng)做一個(gè)主要為展示用的首屏?xí)r,通常會(huì)加載較多的資源例如圖片等,如果我們不想在用戶打開(kāi)時(shí)就加載所有資源,而是希望用戶滾動(dòng)到相關(guān)位置時(shí)再加載組件,此時(shí)就可以選擇IntersectionObserver這個(gè)接口,當(dāng)然也可以使用onscroll事件去做一個(gè)監(jiān)聽(tīng),只不過(guò)這樣性能可能比較差一些。還有一些組件,我們希望他必須要加載,但是又不希望他在初始化頁(yè)面時(shí)同步加載,這樣我們可以使用異步的方式比如Promise和setTimeout等,但是如果想再降低這個(gè)組件加載的優(yōu)先級(jí),我們就可以考慮requestIdleCallback這個(gè)接口,相關(guān)代碼在https://github.com/WindrunnerMax/webpack-simple-environment的vue--first-screen-optimization分支。

IntersectionObserver

IntersectionObserver接口,從屬于Intersection Observer API,提供了一種異步觀察目標(biāo)元素與其祖先元素或頂級(jí)文檔視窗viewport交叉狀態(tài)的方法,祖先元素與視窗viewport被稱為根root,也就是說(shuō)IntersectionObserver API,可以自動(dòng)觀察元素是否可見(jiàn),由于可見(jiàn)visible的本質(zhì)是,目標(biāo)元素與視口產(chǎn)生一個(gè)交叉區(qū),所以這個(gè)API叫做交叉觀察器,兼容性https://caniuse.com/?search=IntersectionObserver。

const io = new IntersectionObserver(callback, option);

// 開(kāi)始觀察
io.observe(document.getElementById("example"));
// 停止觀察
io.unobserve(element);
// 關(guān)閉觀察器
io.disconnect();
  • 參數(shù)callback,創(chuàng)建一個(gè)新的IntersectionObserver對(duì)象后,當(dāng)其監(jiān)聽(tīng)到目標(biāo)元素的可見(jiàn)部分穿過(guò)了一個(gè)或多個(gè)閾thresholds時(shí),會(huì)執(zhí)行指定的回調(diào)函數(shù)。
  • 參數(shù)option,IntersectionObserver構(gòu)造函數(shù)的第二個(gè)參數(shù)是一個(gè)配置對(duì)象,其可以設(shè)置以下屬性:
    • threshold屬性決定了什么時(shí)候觸發(fā)回調(diào)函數(shù),它是一個(gè)數(shù)組,每個(gè)成員都是一個(gè)門(mén)檻值,默認(rèn)為[0],即交叉比例intersectionRatio達(dá)到0時(shí)觸發(fā)回調(diào)函數(shù),用戶可以自定義這個(gè)數(shù)組,比如[0, 0.25, 0.5, 0.75, 1]就表示當(dāng)目標(biāo)元素0%、25%、50%、75%、100%可見(jiàn)時(shí),會(huì)觸發(fā)回調(diào)函數(shù)。
    • root屬性指定了目標(biāo)元素所在的容器節(jié)點(diǎn)即根元素,目標(biāo)元素不僅會(huì)隨著窗口滾動(dòng),還會(huì)在容器里面滾動(dòng),比如在iframe窗口里滾動(dòng),這樣就需要設(shè)置root屬性,注意,容器元素必須是目標(biāo)元素的祖先節(jié)點(diǎn)。
    • rootMargin屬性定義根元素的margin,用來(lái)擴(kuò)展或縮小rootBounds這個(gè)矩形的大小,從而影響intersectionRect交叉區(qū)域的大小,它使用CSS的定義方法,比如10px 20px 30px 40px,表示top、right、bottom和left四個(gè)方向的值。
  • 屬性IntersectionObserver.root只讀,所監(jiān)聽(tīng)對(duì)象的具體祖先元素element,如果未傳入值或值為null,則默認(rèn)使用頂級(jí)文檔的視窗。
  • 屬性IntersectionObserver.rootMargin只讀,計(jì)算交叉時(shí)添加到根root邊界盒bounding box的矩形偏移量,可以有效的縮小或擴(kuò)大根的判定范圍從而滿足計(jì)算需要,此屬性返回的值可能與調(diào)用構(gòu)造函數(shù)時(shí)指定的值不同,因此可能需要更改該值,以匹配內(nèi)部要求,所有的偏移量均可用像素pixel、px或百分比percentage、%來(lái)表達(dá),默認(rèn)值為0px 0px 0px 0px。
  • 屬性IntersectionObserver.thresholds只讀,一個(gè)包含閾值的列表,按升序排列,列表中的每個(gè)閾值都是監(jiān)聽(tīng)對(duì)象的交叉區(qū)域與邊界區(qū)域的比率,當(dāng)監(jiān)聽(tīng)對(duì)象的任何閾值被越過(guò)時(shí),都會(huì)生成一個(gè)通知Notification,如果構(gòu)造器未傳入值,則默認(rèn)值為0。
  • 方法IntersectionObserver.disconnect(),使IntersectionObserver對(duì)象停止監(jiān)聽(tīng)工作。
  • 方法IntersectionObserver.observe(),使IntersectionObserver開(kāi)始監(jiān)聽(tīng)一個(gè)目標(biāo)元素。
  • 方法IntersectionObserver.takeRecords(),返回所有觀察目標(biāo)的IntersectionObserverEntry對(duì)象數(shù)組。
  • 方法IntersectionObserver.unobserve(),使IntersectionObserver停止監(jiān)聽(tīng)特定目標(biāo)元素。

此外當(dāng)執(zhí)行callback函數(shù)時(shí),會(huì)傳遞一個(gè)IntersectionObserverEntry對(duì)象參數(shù),其提供的信息如下。

  • time:可見(jiàn)性發(fā)生變化的時(shí)間,是一個(gè)高精度時(shí)間戳,單位為毫秒。
  • target:被觀察的目標(biāo)元素,是一個(gè)DOM節(jié)點(diǎn)對(duì)象。
  • rootBounds:根元素的矩形區(qū)域的信息,是getBoundingClientRect方法的返回值,如果沒(méi)有根元素即直接相對(duì)于視口滾動(dòng),則返回null。
  • boundingClientRect:目標(biāo)元素的矩形區(qū)域的信息。
  • intersectionRect:目標(biāo)元素與視口或根元素的交叉區(qū)域的信息。
  • intersectionRatio:目標(biāo)元素的可見(jiàn)比例,即intersectionRect占boundingClientRect的比例,完全可見(jiàn)時(shí)為1,完全不可見(jiàn)時(shí)小于等于0。
{
  time: 3893.92,
  rootBounds: ClientRect {
    bottom: 920,
    height: 1024,
    left: 0,
    right: 1024,
    top: 0,
    width: 920
  },
  boundingClientRect: ClientRect {
     // ...
  },
  intersectionRect: ClientRect {
    // ...
  },
  intersectionRatio: 0.54,
  target: element
}

requestIdleCallback

requestIdleCallback方法能夠接受一個(gè)函數(shù),這個(gè)函數(shù)將在瀏覽器空閑時(shí)期被調(diào)用,這使開(kāi)發(fā)者能夠在主事件循環(huán)上執(zhí)行后臺(tái)和低優(yōu)先級(jí)工作,而不會(huì)影響延遲關(guān)鍵事件,如動(dòng)畫(huà)和輸入響應(yīng),函數(shù)一般會(huì)按先進(jìn)先調(diào)用的順序執(zhí)行,如果回調(diào)函數(shù)指定了執(zhí)行超時(shí)時(shí)間timeout,則有可能為了在超時(shí)前執(zhí)行函數(shù)而打亂執(zhí)行順序,兼容性https://caniuse.com/?search=requestIdleCallback。

const handle = window.requestIdleCallback(callback[, options]);
  • requestIdleCallback方法返回一個(gè)ID,可以把它傳入window.cancelIdleCallback()方法來(lái)結(jié)束回調(diào)。
  • 參數(shù)callback,一個(gè)在事件循環(huán)空閑時(shí)即將被調(diào)用的函數(shù)的引用,函數(shù)會(huì)接收到一個(gè)名為IdleDeadline的參數(shù),這個(gè)參數(shù)可以獲取當(dāng)前空閑時(shí)間以及回調(diào)是否在超時(shí)時(shí)間前已經(jīng)執(zhí)行的狀態(tài)。
  • 參數(shù)options可選,包括可選的配置參數(shù),具有如下屬性:
    • timeout: 如果指定了timeout,并且有一個(gè)正值,而回調(diào)在timeout毫秒過(guò)后還沒(méi)有被調(diào)用,那么回調(diào)任務(wù)將放入事件循環(huán)中排隊(duì),即使這樣做有可能對(duì)性能產(chǎn)生負(fù)面影響。

實(shí)現(xiàn)

實(shí)際上編寫(xiě)組件主要是搞清楚如何使用這兩個(gè)主要的API就好,首先關(guān)注IntersectionObserver,因?yàn)榭紤]需要使用動(dòng)態(tài)組件<component />,那么我們向其傳值的時(shí)候就需要使用異步加載組件() => import("component")的形式。監(jiān)聽(tīng)的時(shí)候,可以考慮加載完成之后即銷(xiāo)毀監(jiān)聽(tīng)器,或者離開(kāi)視覺(jué)區(qū)域后就將其銷(xiāo)毀等,這方面主要是策略問(wèn)題。在頁(yè)面銷(xiāo)毀的時(shí)候就必須將Intersection Observer進(jìn)行disconnect,防止內(nèi)存泄漏。使用requestIdleCallback就比較簡(jiǎn)單了,只需要將回調(diào)函數(shù)執(zhí)行即可,同樣也類似于Promise.resolve().then這種異步處理的情況。

這里是簡(jiǎn)單的實(shí)現(xiàn)邏輯,通常observer的使用方案是先使用一個(gè)div等先進(jìn)行占位,然后在observer監(jiān)控其占位的容器,當(dāng)容器在視區(qū)時(shí)加載相關(guān)的組件,相關(guān)的代碼在https://github.com/WindrunnerMax/webpack-simple-environment的vue--first-screen-optimization分支,請(qǐng)盡量使用yarn進(jìn)行安裝,可以使用yarn.lock文件鎖住版本,避免依賴問(wèn)題。使用npm run dev運(yùn)行之后可以在Console中看到這四個(gè)懶加載組件created創(chuàng)建的順序,其中A的observer懶加載是需要等其加載頁(yè)面渲染完成之后,判斷在可視區(qū),才進(jìn)行加載,首屏使能夠直接看到的,而D的懶加載則是需要將滾動(dòng)條滑動(dòng)到D的外部容器出現(xiàn)在視圖之后才會(huì)出現(xiàn),也就是說(shuō)只要不滾動(dòng)到底部是不會(huì)加載D組件的,另外還可以通過(guò)component-params和component-events將attrs和listeners傳遞到懶加載的組件,類似于$attrs和$listeners,至此懶加載組件已簡(jiǎn)單實(shí)現(xiàn)。

<!-- App.vue -->
<template>
    <div>
        <section>1</section>
        <section>
            <div>2</div>
            <lazy-load
                :lazy-component="Example"
                type="observer"
                :component-params="{ content: 'Example A' }"
                :component-events="{
                    'test-event': testEvent,
                }"
            ></lazy-load>
        </section>
        <section>
            <div>3</div>
            <lazy-load
                :lazy-component="Example"
                type="idle"
                :component-params="{ content: 'Example B' }"
                :component-events="{
                    'test-event': testEvent,
                }"
            ></lazy-load>
        </section>
        <section>
            <div>4</div>
            <lazy-load
                :lazy-component="Example"
                type="lazy"
                :component-params="{ content: 'Example C' }"
                :component-events="{
                    'test-event': testEvent,
                }"
            ></lazy-load>
        </section>
        <section>
            <div>5</div>
            <lazy-load
                :lazy-component="Example"
                type="observer"
                :component-params="{ content: 'Example D' }"
                :component-events="{
                    'test-event': testEvent,
                }"
            ></lazy-load>
        </section>
    </div>
</template>

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import LazyLoad from "./components/lazy-load/lazy-load.vue";
@Component({
    components: { LazyLoad },
})
export default class App extends Vue {
    protected Example = () => import("./components/example/example.vue");

    protected testEvent(content: string) {
        console.log(content);
    }
}
</script>

<style lang="scss">
@import "./common/styles.scss";
body {
    padding: 0;
    margin: 0;
}
section {
    margin: 20px 0;
    color: #fff;
    height: 500px;
    background: $color-blue;
}
</style>

每日一題

https://github.com/WindrunnerMax/EveryDay

參考

  • https://www.ruanyifeng.com/blog/2016/11/intersectionobserver_api.html
  • https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserver
  • https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestIdleCallback

總結(jié)

到此這篇關(guān)于Vue項(xiàng)目首屏性能優(yōu)化組件的文章就介紹到這了,更多相關(guān)Vue首屏性能優(yōu)化組件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • element-ui el-select下拉框el-date-picker彈出框定位問(wèn)題解決方案(推薦)

    element-ui el-select下拉框el-date-picker彈出框定位問(wèn)題解決方案(推薦)

    項(xiàng)目開(kāi)發(fā)過(guò)程中發(fā)現(xiàn)el-select和el-date-picker彈出框顯示時(shí)候,滾動(dòng)屏幕,導(dǎo)致彈出框定位出現(xiàn)問(wèn)題,這篇文章主要介紹了element-ui el-select下拉框el-date-picker彈出框定位問(wèn)題解決方案(推薦),需要的朋友可以參考下
    2024-07-07
  • vue ssr+koa2構(gòu)建服務(wù)端渲染的示例代碼

    vue ssr+koa2構(gòu)建服務(wù)端渲染的示例代碼

    這篇文章主要介紹了vue ssr+koa2構(gòu)建服務(wù)端渲染的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • Vue2實(shí)現(xiàn)未登錄攔截頁(yè)面功能的基本步驟和示例代碼

    Vue2實(shí)現(xiàn)未登錄攔截頁(yè)面功能的基本步驟和示例代碼

    在Vue 2中實(shí)現(xiàn)未登錄攔截頁(yè)面功能,通??梢酝ㄟ^(guò)路由守衛(wèi)和全局前置守衛(wèi)來(lái)完成,以下是一個(gè)基本的實(shí)現(xiàn)步驟和示例代碼,幫助你創(chuàng)建一個(gè)簡(jiǎn)單的未登錄攔截邏輯,需要的朋友可以參考下
    2024-04-04
  • vue3中Fragment特性的一個(gè)bug需要注意事項(xiàng)

    vue3中Fragment特性的一個(gè)bug需要注意事項(xiàng)

    這篇文章主要介紹了vue3中Fragment特性的一個(gè)bug,需要留意的注意事項(xiàng)示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • vue router路由嵌套不顯示問(wèn)題的解決方法

    vue router路由嵌套不顯示問(wèn)題的解決方法

    這篇文章主要為大家詳細(xì)介紹了vue router路由嵌套不顯示的問(wèn)題,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下vue-router 路由嵌套不顯示問(wèn)題
    2017-06-06
  • vue等兩個(gè)接口都返回結(jié)果再執(zhí)行下一步的實(shí)例

    vue等兩個(gè)接口都返回結(jié)果再執(zhí)行下一步的實(shí)例

    這篇文章主要介紹了vue等兩個(gè)接口都返回結(jié)果再執(zhí)行下一步的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09
  • Vue3中v-slot的特性深度剖析

    Vue3中v-slot的特性深度剖析

    在Vue3架構(gòu)里,v-slot 作為作用域插槽的關(guān)鍵支撐,重塑了父子組件間數(shù)據(jù)與方法傳遞的范式,本文主要來(lái)和大家剖析一下v-slot的相關(guān)特性,需要的可以了解下
    2025-01-01
  • Vue.js中數(shù)組變動(dòng)的檢測(cè)詳解

    Vue.js中數(shù)組變動(dòng)的檢測(cè)詳解

    這篇文章給大家主要介紹了Vue.js中數(shù)組變動(dòng)的檢測(cè),文中給出了詳細(xì)的示例代碼和過(guò)程介紹,相信會(huì)對(duì)大家的理解和學(xué)習(xí)很有幫助,有需要的朋友們下面來(lái)一起看看吧。
    2016-10-10
  • 解決Vue2.x父組件與子組件之間的雙向綁定問(wèn)題

    解決Vue2.x父組件與子組件之間的雙向綁定問(wèn)題

    這篇文章主要介紹了解決Vue2.x父組件與子組件之間的雙向綁定問(wèn)題,需要的朋友可以參考下
    2018-03-03
  • vue3使用Vite打包組件庫(kù)從0搭建過(guò)程詳解

    vue3使用Vite打包組件庫(kù)從0搭建過(guò)程詳解

    這篇文章主要為大家介紹了vue3使用Vite打包組件庫(kù)從0搭建過(guò)程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02

最新評(píng)論