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

詳解節(jié)點(diǎn)監(jiān)控相對準(zhǔn)確的計(jì)算FMP

 更新時(shí)間:2023年01月10日 16:45:45   作者:木羽  
這篇文章主要為大家介紹了節(jié)點(diǎn)監(jiān)控相對準(zhǔn)確的計(jì)算FMP詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

上篇講到,權(quán)重值定位性能指標(biāo) FMP,至于怎么算權(quán)重講的不是很清楚,此篇將就如何「相對準(zhǔn)確」算出權(quán)重值以及怎樣篩選出我們想要的 FMP 值。

以下內(nèi)容「擇重略輕」

如何監(jiān)控節(jié)點(diǎn)

監(jiān)控變化

MutationObserver

一句話解釋

「MutationObserver 給予我們獲取 DOM 渲染「切面」的能力」。

「MDN 解釋」MutationObserver 接口提供了監(jiān)視對 DOM 樹所做更改的能力。它被設(shè)計(jì)為舊的 Mutation Events 功能的替代品,該功能是 DOM3 Events 規(guī)范的一部分。

更多使用細(xì)節(jié)詳見 https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver

節(jié)點(diǎn)標(biāo)記

有了以上能力,既可以對節(jié)點(diǎn)進(jìn)行監(jiān)聽和 「標(biāo)記」

像這樣

// 偽代碼
new MutationObserver(() => {
    let timestamp = performance.now() || (Date.now() - START_TIME),
    doTag(document.body, global.paintTag++);
    global.ptCollector.push(timestamp);
});

名詞解釋: - paintTag:對應(yīng) dom 的打點(diǎn)標(biāo)記「_pi」,標(biāo)記著第幾次配渲染的產(chǎn)物。

  • ptCollector:paintTag 對應(yīng)的時(shí)間節(jié)點(diǎn)集合??梢杂?paintTag 檢索到某次渲染時(shí)刻的時(shí)間節(jié)點(diǎn)。

什么時(shí)間計(jì)算?

window.load 開始計(jì)算

為什么?

我們認(rèn)為,通常情況下,在 window 觸發(fā) load 事件的時(shí)刻,意味著主要業(yè)務(wù)的 90% 的資源和 dom 都已經(jīng)準(zhǔn)備就緒。此時(shí)算出的高權(quán)重得分的 dom 就是我們想要找的 FMP 關(guān)鍵節(jié)點(diǎn)。

我不關(guān)心你是怎么渲染的,異步也好直出也好,殊途同歸,我只關(guān)心結(jié)果

怎么篩選元素?

計(jì)算權(quán)重得分

基礎(chǔ)節(jié)點(diǎn)

一個(gè)基礎(chǔ)節(jié)點(diǎn)(無子節(jié)點(diǎn))的權(quán)重得分計(jì)算方法:

// 偽代碼
const TAG_WEIGHT_MAP = {
    SVG: 2,
    IMG: 2,
    CANVAS: 2,
    VIDEO: 4
};
node => {
    let weight = TAG_WEIGHT_MAP[node.tagName],
        areaPercent = global.calculateShowPercent(node);
    let score = width * height * weight * areaPercent;
    return score;
}

關(guān)于 calculateShowPercent 用下圖解釋

父節(jié)點(diǎn)

這是一個(gè)算法我把它叫做「代父競選」

父節(jié)點(diǎn)自身的權(quán)重得分計(jì)算方法同基礎(chǔ)節(jié)點(diǎn)相同,不同的是,如果其子節(jié)點(diǎn)的得分和大于或等于了自身的得分,將由子節(jié)點(diǎn)組代替父節(jié)點(diǎn)參與更高級的競選,同時(shí),子節(jié)點(diǎn)的權(quán)重得分和作為父節(jié)點(diǎn)的得分,另外,如果子節(jié)點(diǎn)是有孫子節(jié)點(diǎn)代表的,孫子節(jié)點(diǎn)將會同步升級。

怎么理解呢?

如下兩種情況:

父元素得分 = 400 * 100 = 40000
子元素得分和 = 300 * 60 + 60 * 60 = 21600
父元素得分 > 子元素得分和

此情況下,該組元素以 40000 的得分進(jìn)入下一級競選。參選的元素列表為父元素本身。

數(shù)據(jù)結(jié)構(gòu)如下:

{
    deeplink: [{…}],
    elements: [{
        node: parent#id_search,
        ...
    }],
    node: parent#id_search,
    paintIndex: 1,
    score: 40000
}

父元素得分 = 400 * 300 = 120000
子元素得分和 = 400 * 300 + 60 * 100 = 126000
父元素得分 < 子元素得分和

此情況下,該組元素應(yīng)以 126000 的得分進(jìn)入下一級競選。參選的元素列表為子元素組,「代父競選」。

數(shù)據(jù)結(jié)構(gòu)如下:

{
    deeplink: [{…}],
    elements: [
        {node: child#id_slides_pics, ...},
        {node: child#id_slides_index, ...}
    ],
    node: parent#id_slides,
    paintIndex: 2,
    score: 126000
}

由以上兩種情況可推

父元素得分 = 400 * 400 = 160000
子元素得分和 = 40000 + 126000 = 166000
父元素得分 < 子元素得分和
其中一個(gè)子節(jié)點(diǎn)由孫子節(jié)點(diǎn)們代表

 ==>

{
    deeplink: [{…}],
    elements: [
        {node: child#id_search, ...},
        {node: child#id_slides_pics, ...},
        {node: child#id_slides_index, ...}
    ],
    node: parent#id_body,
    paintIndex: 1,
    score: 166000
}

所以,以下組合與拆分就不難理解了。

排除干擾項(xiàng)

在我們對 document 深度遍歷計(jì)算的過程中,總會遇到一些干擾因素使我們的腳本計(jì)算出錯(cuò),以下兩種就是最常見的

不可見元素

這種元素雖然用戶無感知,但會嚴(yán)重影響最后的競選結(jié)果。

處理方案

const isIgnoreDom = node => {
    return getStyle(node, 'opacity') < 0.1 ||
        getStyle(node, 'visibility') === 'hidden' ||
        getStyle(node, 'display') === 'none' ||
        node.children.length === 0 &&
        getStyle(node, 'background-image') === 'none' &&
        getStyle(node, 'background-color') === 'rgba(0, 0, 0, 0)';
}

首先我們認(rèn)為opacity < 0.1 visibility === 'hidden' 和 display === 'none' 的元素為不可見元素,應(yīng)忽略,另外,無子節(jié)點(diǎn),且無背景無顏色的元素也歸屬于不可見元素,忽略。

滾動偏移

由于我們的腳本在 window load 后才執(zhí)行,絕大情況下此時(shí)瀏覽器的滾動條已經(jīng)發(fā)生了偏移。精選結(jié)果會發(fā)生誤差。如下圖:

此時(shí)精選結(jié)果為

<div class="channel" _pi="30">...</div>

_pi 走到了 30,「第 30 次渲染」,無論有多快,這個(gè)值始終會遠(yuǎn)大于實(shí)際的 FMP。

導(dǎo)致「滾動偏移」的情況有兩種

  • 在 load 觸發(fā)前用戶主動翻閱 這種情況再常見不過,用戶不可能每次都等到 load 后才進(jìn)行操作。而且如果存在 pending 的資源,load 的時(shí)間會非常遲。
  • load 瀏覽器觸發(fā)前執(zhí)行了「scrollRestore (英文描述,并不存在此事件)」

對于第二種情況,還是很好解的,因?yàn)椴⒉皇撬械臑g覽器都有 History.scrollRestoration 的特效,所以,我們只要關(guān)掉即可,但情況一我們是無論如何不能控制的。

所以,只能另辟蹊徑「劃定計(jì)算區(qū)域」,且此區(qū)域應(yīng)避開滾動條位置的影響。

處理方案

當(dāng)然,我們也是有方法的,其實(shí)也挺簡單。

這得益于「document 對象的寬高是固定的,且偏移量同步于滾動條」

const getDomBounding = dom => {
    const { x, y } = document.body.getBoundingClientRect();
    const { left, right, top, bottom, width, height } = dom.getBoundingClientRect();
    return {
        left: left - x,
        right: right - x,
        top: top - y,
        bottom: bottom - y,
        height, width
    }
}

 如果以上有遺漏情況,還請不吝賜教,不勝感激!

不同元素 FMP 算法不同

普通元素

像 <DIV/>、<SPAN/>、<P/>、<INPUT/> 這些普通元素,標(biāo)注的 _pi 值索引到的渲染時(shí)刻的時(shí)間節(jié)點(diǎn) ptCollector 還記得嗎?該時(shí)間即可作為 FMP 值。

有特殊情況,如果普通元素帶有背景圖片,則會升級為 <IMG/> 類資源元素

資源元素

如 <IMG/><VIDEO/>,該元素的 resource 的 responseEnd 的時(shí)間節(jié)點(diǎn)將作為 FMP 值

不過,我們可以針對不同的項(xiàng)目對全局權(quán)重配置 TAG_WEIGHT_MAP 做「合理化」調(diào)整。當(dāng)然也可以忽略「圖片」和「視頻」等資源元素資源加載時(shí)間,一切以實(shí)際項(xiàng)目而定

以上就是詳解節(jié)點(diǎn)監(jiān)控相對準(zhǔn)確的計(jì)算FMP的詳細(xì)內(nèi)容,更多關(guān)于節(jié)點(diǎn)監(jiān)控FMP計(jì)算的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論