前端性能指標(biāo)--首屏?xí)r間統(tǒng)計(jì)
Labs 導(dǎo)讀
隨著公司的高速發(fā)展,業(yè)務(wù)需求越來越多,用戶和公司對于頁面的穩(wěn)定性、性能也有了更高的訴求。根據(jù)Aberdeen Group的調(diào)研發(fā)現(xiàn)從瀏覽器輸入地址開始訪問到頁面展示的最佳時(shí)間為3秒內(nèi),每多一秒的延遲會使客戶滿意度降低16%。
Part 01、 白屏和首屏?xí)r間
? 白屏:從用戶請求頁面開始到顯示第一個字符的時(shí)間。中間包括DNS查詢、建立TCP鏈接、發(fā)送首個HTTP請求、返回HTML文檔、HTML文檔head解析完畢。通常認(rèn)為瀏覽器開始渲染<body>標(biāo)簽或者解析完<head>標(biāo)簽的時(shí)刻就是頁面白屏結(jié)束的時(shí)間點(diǎn)。
? 首屏:指用戶打開網(wǎng)站開始,到瀏覽器首屏內(nèi)容渲染完成的時(shí)間,對于用戶體驗(yàn)來說,首屏?xí)r間是用戶對一個網(wǎng)站的重要體驗(yàn)因素。
Part 02、 PerformanceTiming
performance.timing記錄了用于分析頁面整體性能指標(biāo)的關(guān)鍵時(shí)間點(diǎn),包含網(wǎng)絡(luò)、解析等一系列的時(shí)間數(shù)據(jù)。最好在頁面完全加載完成之后再使用,因?yàn)楹芏嘀当仨氃陧撁嫱耆虞d之后才能得到。最簡單的辦法是在window.onload(vm.$nextTick 或 react hooks useEffect)事件中讀取各種數(shù)據(jù)。
在瀏覽器控制臺,console輸入performance可以查看到performance.timing相關(guān)時(shí)間節(jié)點(diǎn):
通過PerformanceTiming不僅可以幫助我們省去繁瑣的手動打點(diǎn)操作,還可以幫助我們獲取很多其他數(shù)據(jù),對于整個時(shí)間節(jié)點(diǎn)的對應(yīng)關(guān)系:下圖顯示了PerformanceTiming中定義的所有時(shí)間戳屬性。
比較有用的頁面性能數(shù)據(jù)大概包括如下幾個:
- 重定向耗時(shí):redirectEnd - redirectStart
- DNS查詢耗時(shí):domainLookupEnd - domainLookupStart
- TCP鏈接耗時(shí):connectEnd - connectStart
- HTTP請求耗時(shí):responseEnd - responseStart
- 解析dom樹耗時(shí):domComplete - domInteractive
- 白屏?xí)r間:responseStart - navigationStart
- DOM ready時(shí)間:domContentLoadedEventEnd - navigationStart
- onload時(shí)間:loadEventEnd - navigationStart
Part 03、MutationObserver API
MutationObserver API讓我們能監(jiān)聽DOM樹變化,在首屏的加載中,會涉及到DOM的增加、修改、刪除,所以會觸發(fā)多次MutationObserver。
1)利用MutationObserver監(jiān)聽document對象,每當(dāng)dom變化時(shí)觸發(fā)回調(diào)函數(shù)
2)判斷監(jiān)聽的dom是否在首屏內(nèi),如果在首屏內(nèi),將該dom放到指定的數(shù)組中,記錄下當(dāng)前dom變化的時(shí)間點(diǎn)
3)在MutationObserver的callback函數(shù)中,通過防抖函數(shù),監(jiān)聽document.readyState狀態(tài)的變化
4)當(dāng)document.readyState === 'complete',停止定時(shí)器和 取消對document的監(jiān)聽
5)遍歷存放dom的數(shù)組,找出最后變化節(jié)點(diǎn)的時(shí)間,就是首屏加載完成的時(shí)間
監(jiān)聽container外層容器的變化 ,當(dāng)觸發(fā)回調(diào)函數(shù)時(shí),判斷對應(yīng)的事件類型以及新增加的子dom是否是首屏展示的dom節(jié)點(diǎn)。
圖片
盡管現(xiàn)在的MutationObserver 在移動端兼容性比較好,但為了更好的兼容,我們可以另外引入 MutationEvents API。
Part 04、 webview里H5頁面首屏?xí)r間
圖片
4.1 WebView初始化階段
該階段包括幾個主要步驟:
(1)開始解析Url(Url中可能包含${}需要解析的字段)
(2)完成解析Url
(3)開始校驗(yàn)Url是否可以打開
(4)結(jié)束校驗(yàn)Url
(5)開始加載Url到webview容器和家親app jsbridge提供了getPerformInfo方法可以幫助我們獲取WebView性能數(shù)據(jù):
WebViewUrlLoaded WebView加載url時(shí)間:startLoadUrl(開始加載Url到webview容器) - startProcessUrl(開始解析Url);
4.2 HTTP請求服務(wù)階段
該階段包括幾個主要步驟:
(1)DNS查詢
(2) 等待 TCP 隊(duì)列
(3) TCP鏈接
(4) 發(fā)起http請求和響應(yīng)
(5) 服務(wù)器端處理 HTTP 請求 ,服務(wù)器端處理 HTTP 請求,瀏覽器得到html代碼
(6) 開始head解析
該階段的時(shí)間從webview容器開始加載Url開始到完成head解析,可以使用window.performance.timing.responseStart - startLoadUrl(開始加載Url到webview容器)
4.3 靜態(tài)資源下載
該階段包括幾個主要步驟:
(1)head解析 并開始請求靜態(tài)資源(如js、css、圖片等)
(2) 靜態(tài)資源下載完成
(3) 開始解析靜態(tài)資源
該階段的時(shí)間從開始請求靜態(tài)資源,到開始解析靜態(tài)資源(比如 JS),我們可以在js文件開始自定義JscriptLaunch字段,并賦值給window.preformance對象,(window.PerformInfo || (window.PerformInfo = {})).JscriptLaunch = new Date().getTime(); 以便于我們統(tǒng)計(jì)該階段的時(shí)間:window.PerformInfo.JscriptLaunch - window.performance.timing.responseStart。
4.4 API調(diào)用和首屏dom渲染
該階段包括幾個主要步驟:
(1) 開始解析靜態(tài)資源,請求API
(2) 響應(yīng)數(shù)據(jù)
(3) 下載資源并渲染dom
(4) 首屏內(nèi)容加載完成
利用MutationObserver監(jiān)控DOM的變化,獲取首屏dom加載完成的時(shí)間,用該時(shí)間點(diǎn) 減去window.PerformInfo.JscriptLaunch,就獲得了該階段的時(shí)間。
Part 05、 數(shù)據(jù)上報(bào)
將統(tǒng)計(jì)到的數(shù)據(jù)以圖片打點(diǎn)、fetch請求或Beacon等形式進(jìn)行上報(bào),可以幫助我們后續(xù)進(jìn)行分析和優(yōu)化。
- 直接發(fā)請求上報(bào)
直接將數(shù)據(jù)通過 ajax 發(fā)送到后端有一個問題,就是在頁面卸載或刷新時(shí)進(jìn)行上報(bào)的話,請求可能會在瀏覽器關(guān)閉或重新加載前還未發(fā)送至服務(wù)端就被瀏覽器 cancel 掉,導(dǎo)致數(shù)據(jù)上報(bào)失敗。
- 利用圖片上報(bào)
服務(wù)器端并不關(guān)心具體的數(shù)據(jù)上報(bào)方式,無論是請求image文件還是請求其他普通文件(JS)或者是請求接口,可以進(jìn)行數(shù)據(jù)上報(bào),
使用image有幾個優(yōu)點(diǎn):
- 圖片的src屬性并不會跨域,不會出現(xiàn)跨域問題;
- 大部分瀏覽器會延遲卸載(unload)文檔以加載圖像,可以避免第一種方法的問題
- 只要在js中new出Image對象就能發(fā)起請求,不用插入dom中,可以防止阻塞頁面加載,影響用戶體驗(yàn)
- 相比PNG/JPG,GIF的體積最小,最適合進(jìn)行上報(bào),一般采用1*1像素的透明 gif 進(jìn)行上報(bào)
- 通過css定義content,按鈕點(diǎn)擊就會上報(bào),但是不能動態(tài)傳入一些變量
圖片
- Beacon
Beacon可將數(shù)據(jù)異步發(fā)送至服務(wù)端,且可能保障在頁面卸載實(shí)現(xiàn)前發(fā)送申請(解決頁面卸載會終止請求的問題)
圖片
Part 06、 總結(jié)
頁面首屏加載時(shí)間是個重要的性能指標(biāo),通過上面的方式對首屏?xí)r間進(jìn)行統(tǒng)計(jì)分析,可以幫助我們有針對性的進(jìn)行性能優(yōu)化。同時(shí)頁面性能的提升,帶給用戶更好的產(chǎn)品體驗(yàn),這樣才會得到好的產(chǎn)品反饋,給企業(yè)帶來價(jià)值。