欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS前端性能指標定位FMP使用詳解

 更新時間:2023年01月10日 16:17:05   作者:木羽ZW  
這篇文章主要為大家介紹了JS前端性能指標定位FMP使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

什么是FMP?

可能大家對「白屏時間」這個名詞并不陌生,他是「刀耕火種」年代,我們收集的頁面性能指標之一,隨著前端工程的復雜化,白屏時間已經(jīng)沒有什么實質(zhì)性的意義了,取而代之的就是 FMP。

先來介紹幾個與之相關的名詞。

  • FP(First Paint):首次繪制,標記瀏覽器渲染任何在視覺上不同于導航前屏幕內(nèi)容的時間點
  • FCP(First Contentful Paint):首次內(nèi)容繪制,標記的是瀏覽器渲染第一針內(nèi)容 DOM 的時間點,該內(nèi)容可能是文本、圖像、SVG 或者 <canvas> 等元素
  • FMP(First Meaning Paint):首次有效繪制,標記主角元素渲染完成的時間點,主角元素可以是視頻網(wǎng)站的視頻控件,內(nèi)容網(wǎng)站的頁面框架也可以是資源網(wǎng)站的頭圖等。

相對于 FP 和 FCP,F(xiàn)MP 是我們前端最常關注的重要性能指標,Google 定義它為「是否有用?」的時間點。然而,「是否有用?」是很難以通用方式界定的,因此,至今依然沒有標準的 API 輸出。

社區(qū)中常有這么幾種方式進行「相對準確」的計算 FMP,所謂相對準確,是相對于實際項目而言。

  • 主動上報:開發(fā)者在相應頁面的「Meaning」位置上報時間
  • 權重計算:根據(jù)頁面元素,計算權重最高的元素渲染時間
  • 趨勢計算:在 render 期間,根據(jù) dom 的變化趨勢推算 FMP 值

本文將著重介紹第二種方式。

權重定位

所謂權重,即,將頁面的元素以約定的「權重比」遍歷出「權重值」最大的某一個或一組 DOM,然后以其「裝載時間點」或「加載結(jié)束點」作為 FMP 的映射。

權重計算

節(jié)點標記

想要對 DOM 節(jié)點進行階段性標記,就得有監(jiān)聽 DOM 變化的能力,慶幸的是,HTML5 賦予了我們這個能力。

MutationObserver,Mutation Events功能的替代品,是DOM3 Events規(guī)范的一部分。他可以在指定的 DOM 發(fā)生變化時執(zhí)行回調(diào)。

MutationObserver 有三個方法

  • disconnect() 阻止 MutationObserver 實例繼續(xù)接收的通知,直到再次調(diào)用其observe()方法,該觀察者對象包含的回調(diào)函數(shù)都不會再被調(diào)用。
  • observe() 配置MutationObserver在DOM更改匹配給定選項時,通過其回調(diào)函數(shù)開始接收通知。
  • takeRecords() 從MutationObserver的通知隊列中刪除所有待處理的通知,并將它們返回到MutationRecord對象的新Array中。
global.mo = new MutationObserver(() => { 
    /* callback: DOM 節(jié)點設置階段性標記 */
});
/**
 * mutationObserver.observe(target[, options])
 * target - 需要觀察變化的 DOM Node。
 * options - MutationObserverInit 對象,配置需要觀察的變化項。
 * 更多 options 的介紹請參考 https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserverInit#%E5%B1%9E%E6%80%A7
 **/
global.mo.observe(document, {
  childList: true,  // 監(jiān)聽子節(jié)點變化(如果subtree為true,則包含子孫節(jié)點)
  subtree: true // 整個子樹的所有節(jié)點
});

下圖粗濾的解析了正常單頁面的渲染過程

  • 預備階段:導航階段,處在連接相應的過程
  • 階段一:首字節(jié)渲染階段,也是FCP,DOM 樹的第一次有效變化
  • 階段二:基本框架渲染完成
  • 階段三:獲取到數(shù)據(jù),渲染到視圖上
  • 階段四:圖片加載完成,加載過程不被標記

實際上在第一、第三階段之間還存在著大量的 DOM 變化,Mutation Observer 事件的觸發(fā)并不是同步的,而是異步觸發(fā)的,也就是說,等到當前「階段」所有 DOM 操作都結(jié)束才觸發(fā)。

Mutation Observer 有以下特點

  • 它等待所有腳本任務完成后,才會運行(即異步觸發(fā)方式)。
  • 它把 DOM 變動記錄封裝成一個數(shù)組進行處理,而不是一條條個別處理 DOM 變動。
  • 它既可以觀察 DOM 的所有類型變動,也可以指定只觀察某一類變動。

load 事件觸發(fā)后,各個階段的 tag 已經(jīng)被打到標簽上了

此處以『_ti』昨晚標記 key。

在打標記的同時,需要記錄下當前的時間節(jié)點,備用

// 偽代碼
function callback() {
    global.timeStack[++_ti] = performance.now(); // 記時間
    doTag(_ti); // 打標記
}

標記打完后就等 load 的那一刻進行計算反推了。

計算權重值

一般來說

  • 視圖占比越大的元素越有可能是主角元素
  • 視頻比圖片更可能是主角元素
  • svgcanvas 也很重要
  • 其他元素都可以按普通 dom 計算了
  • 背景圖片視情況而定,可記可不記

第一步:簡單粗暴,按大小計算

// 偽代碼
function weightCompute(node){
    let {
        width,
        height,
        left,
        top
    } = node.getBoundingClientRect();
    // 排除視圖外的元素
    if(isOutside(width, height, left, top)){
        return 0;
    }
    let wts = TAG_WEIGHT_MAP[node.tagName]; // 約定好的權重比
    let weight = width * height * wts; // 直接乘,或者更細粒度的計算 wts(width, height, wts)
    return {
        weight, 
        wts, 
        tagName: node.tagName, 
        ti: node.getAttribute("_ti"),
        node
    };
}

第二步:根據(jù)權重值推導主角元素

在我們的約定權重算法下,權重最大的元素即為我們推到的主角元素。

// 偽代碼
function getCoreNode(node){
    let list = nodeTraversal(node); // 遞歸計算每個標記節(jié)點的權重值
    return getNodeWithMaxWeight(list); // weight 最大的元素
}

第三步:根據(jù)元素類型取時間

不同的元素獲取時間的方式并不相同

  • 普通元素:按標記點時間計算
  • 圖片和視頻:按資源相應結(jié)束時間計算
  • 帶背景元素:可以以背景資源相應結(jié)束時間計算,也可以按普通元素計算
// 偽代碼
function getFMP(){
    let coreObj = getCoreNode(document.body),
        fmp = -1;
    let {
        tagName,
        ti,
        node
    } = coreObj;
    switch(tagName){
        case 'IMG':
        case 'VIDEO':
            let source = node.src;
            let { responseEnd } = performance.getEntries().find(item => item.name === source);
            fmp = responseEnd || -1;
            break;
        default:
            if(node.style.backgroundImage){
                // 普通元素的背景處理
            }else{
               fmp = global.timeStack[+ti]; 
            }
    }
    return fmp;
}

回歸驗證

以我們的 demo 頁為例,類似的電商網(wǎng)站,我們希望拿到「階段二」或「階段三」的時間點作為我們的 FMP 值。

因為我們并不希望「主角元素」的背景或者「圖片主角元素」的相應時間算在 FMP 的值內(nèi),所以,我們將「圖片」「視頻」等資源元素降級成普通元素計算。

在 Chrome [ Disable cache / Fast 3G ] 條件下我們進行模擬驗證。

計算得到的 FMP 值為 4730.7ms,Chrome Performance 監(jiān)控的值在 4950ms 左右,誤差在 200ms 左右。

如果將限速放開,F(xiàn)MP 的取值將更接近我們希望的「First Meaning Paint」。

以上就是JS前端性能指標定位FMP使用詳解的詳細內(nèi)容,更多關于JS前端性能指標定位FMP的資料請關注腳本之家其它相關文章!

相關文章

最新評論