利用MutationObserver實現(xiàn)計算首屏?xí)r間
一、前言
在前端開發(fā)中,優(yōu)化頁面性能是至關(guān)重要的,計算首屏?xí)r間(First Contentful Paint,F(xiàn)CP)是衡量網(wǎng)頁性能的重要指標,它表示頁面內(nèi)容中的第一個元素被渲染到屏幕上的時間點。而MutationObserver是一種強大的JavaScript API,可以用于監(jiān)聽DOM的變化,并幫助開發(fā)者計算首屏?xí)r間,即頁面加載后第一次渲染完畢的時間點。本文將介紹如何使用MutationObserver來獲取首屏?xí)r間的最佳實踐,并提供具體的原理分析、代碼示例以及其他應(yīng)用場景。
二、原理分析
MutationObserver利用了瀏覽器的MutationObserver接口來監(jiān)聽DOM的變化。當DOM樹中的元素發(fā)生變化時,MutationObserver會自動觸發(fā)注冊的回調(diào)函數(shù)。通過在回調(diào)函數(shù)中記錄時間戳,可以計算出首屏?xí)r間,即頁面加載后第一次渲染完畢的時間點。
1.創(chuàng)建MutationObserver對象:通過構(gòu)造函數(shù)MutationObserver
創(chuàng)建一個MutationObserver對象,并傳入一個回調(diào)函數(shù)作為參數(shù)。
2.配置MutationObserver:通過MutationObserver
的配置選項,指定需要監(jiān)測的DOM樹變化類型。常見的配置選項有:
childList
:是否監(jiān)測子節(jié)點的變化,即DOM元素的添加或刪除。attributes
:是否監(jiān)測屬性的變化,比如元素的屬性值發(fā)生變化。characterData
:是否監(jiān)測字符數(shù)據(jù)的變化,比如文本節(jié)點的內(nèi)容發(fā)生變化。subtree
:是否監(jiān)測整個DOM子樹的變化,包括子節(jié)點及其后代節(jié)點的變化。
3.觀察DOM樹:將MutationObserver對象與需要觀察的目標節(jié)點(通常是文檔對象document)關(guān)聯(lián)起來,開始監(jiān)測DOM樹的變化。
observer.observe(targetNode, observerConfig);
4.監(jiān)測DOM樹變化:一旦MutationObserver開始觀察,它會監(jiān)測指定的DOM樹變化類型。當DOM樹發(fā)生符合指定類型的變化時,會觸發(fā)回調(diào)函數(shù),并將變化的信息傳遞給回調(diào)函數(shù)作為參數(shù)。
function callback(mutationsList, observer) { // 處理DOM樹的變化 }
在回調(diào)函數(shù)中,我們可以遍歷mutationsList
,檢查DOM樹的變化情況,然后根據(jù)需要執(zhí)行相應(yīng)的操作。比如,找到首屏元素并記錄首屏?xí)r間,或者處理其它DOM樹的變化情況。
5.停止觀察:在需要停止觀察DOM樹變化時,我們可以調(diào)用disconnect()
方法來停止MutationObserver的觀察。
observer.disconnect();
三、最佳實踐
1.初始化MutationObserver監(jiān)聽: 在頁面加載后,通過JavaScript代碼創(chuàng)建一個MutationObserver對象,并注冊一個回調(diào)函數(shù)?;卣{(diào)函數(shù)會在DOM樹中的元素發(fā)生變化時自動觸發(fā)。
const observer = new MutationObserver(callback); observer.observe(document, { childList: true, // 監(jiān)測子節(jié)點的變化(元素的添加或刪除) subtree: true // 監(jiān)測子樹的變化(深層元素的修改) });
2.計算DOM變化時的時間: 在回調(diào)函數(shù)中,可以通過檢查DOM元素的變化來判斷頁面是否已經(jīng)渲染完畢。例如,可以檢查頁面中某個元素的可見性、位置或樣式等屬性是否發(fā)生變化,從而判斷頁面的渲染狀態(tài)。
function callback(mutationsList) { let firstScreenTime = 0; mutationsList.forEach(mutation => { // 檢查DOM元素的變化 if (mutation.type === 'attributes' && mutation.attributeName === 'style' && !document.querySelector('.loading').style.display) { // 頁面首屏渲染完畢 firstScreenTime = performance.now(); } }); if (firstScreenTime > 0) { console.log(`首屏?xí)r間:${firstScreenTime}ms`); // 可以在這里執(zhí)行首屏渲染完畢后的操作 } }
3.去掉DOM被刪除情況的監(jiān)聽: 在回調(diào)函數(shù)中,MutationObserver會監(jiān)聽到DOM樹中元素的添加、刪除、屬性變化等多種變化。但在計算首屏?xí)r間時,只關(guān)注DOM的添加和屬性變化即可,因此可以在回調(diào)函數(shù)中去掉對DOM被刪除的情況的監(jiān)聽,從而避免不必要的性能開銷
function callback(mutationsList) { let firstScreenTime = 0; mutationsList.forEach(mutation => { // 只關(guān)注DOM元素的添加和屬性變化 if ((mutation.type === 'attributes' && mutation.attributeName === 'style') || mutation.type === 'childList') { // 檢查DOM元素的變化 // 你可以在這里根據(jù)項目需要查找首屏元素的特定條件,比如特定的CSS類或ID if (!document.querySelector('.loading').style.display) { // 頁面首屏渲染完畢,首屏元素被找到,記錄首屏?xí)r間 firstScreenTime = performance.now(); // 停止觀察,避免重復(fù)計算首屏?xí)r間 observer.disconnect(); } } }); if (firstScreenTime > 0) { console.log(`首屏?xí)r間:${firstScreenTime}ms`); // 可以在這里執(zhí)行首屏渲染完畢后的操作 } }
四、其他應(yīng)用場景
- 動態(tài)表單驗證:在表單中添加MutationObserver,實時監(jiān)測用戶輸入的變化,根據(jù)用戶輸入的內(nèi)容進行實時的表單驗證,提供即時的錯誤提示和反饋。
- 圖片懶加載:對于圖片懶加載技術(shù),可以使用MutationObserver來監(jiān)測圖片元素是否進入了可視區(qū)域,從而在圖片出現(xiàn)在可視區(qū)域內(nèi)時才加載圖片資源,減少頁面的初始加載時間和帶寬消耗。
- 無障礙輔助功能:通過MutationObserver監(jiān)測頁面內(nèi)容的變化,可以實現(xiàn)輔助功能,比如在內(nèi)容動態(tài)更新時提供適當?shù)钠聊婚喿x器提示。
- 防止修改/刪除水印圖片或文字,當觸發(fā)了水印元素的MutationObserver回調(diào)的時候,不去做具體的判斷和恢復(fù)邏輯,而是將這個水印div刪掉并重新生成新的水印div。
到此這篇關(guān)于利用MutationObserver實現(xiàn)計算首屏?xí)r間的文章就介紹到這了,更多相關(guān)MutationObserver計算首屏?xí)r間內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
深入理解JavaScript系列(8) S.O.L.I.D五大原則之里氏替換原則LSP
本章我們要講解的是S.O.L.I.D五大原則JavaScript語言實現(xiàn)的第3篇,里氏替換原則LSP(The Liskov Substitution Principle )。2012-01-01一個Js文件函數(shù)中調(diào)用另一個Js文件函數(shù)的方法演示
這篇文章主要介紹了一個Js文件函數(shù)中調(diào)用另一個Js文件函數(shù)的方法,兩個javascript文件中相互調(diào)用函數(shù),主要是將引入的Js文件代碼放在</body>下面。具體操作方法可查看下文,需要的朋友可以參考下2017-08-08javascript 新聞標題靜態(tài)分頁代碼 (無刷新)
一個模板,從數(shù)據(jù)庫取n條記錄,生成靜態(tài)。做單頁面的靜態(tài)化,索引頁面是用JS對數(shù)組進行組合的。2010-03-03JS 頁面內(nèi)容搜索,類似于 Ctrl+F功能的實現(xiàn)代碼
JS 頁面內(nèi)容搜索,類似于 Ctrl+F功能的實現(xiàn)代碼...2007-08-08javascript引用類型之時間Date和數(shù)組Array
引用類型的值(對象)其實就是引用類型的一個實例,接下來,通過本篇文章給大家介紹javascript引用類型之時間Date和數(shù)組Array,需要的朋友可以參考下2015-08-08