本文首發於知乎《10分鐘徹底搞懂前端頁面效能監控》,搬運轉載請註明出處,否則追究版權責任。
前言
前端頁面效能是一個非常核心的使用者體驗指標。本文介紹阿里UC 嶽鷹全景監控平臺 如何設計一個通用、低侵入性、自動上報的頁面效能監控方案。主要採用的是Navigation Timing API以及sendBeacon等方法。
為什麼要監控頁面效能?
一個頁面效能差的話會大大影響使用者體驗。使用者開啟頁面等待的太久,可能會直接關掉頁面,甚至就不再使用了,這種情況在移動端更加明顯,移動端使用者對頁面響應延遲容忍度很低。
雖然頁面效能很重要,但是在實際使用中,頁面效能差的情況並不少見。首先,在產品的迭代演進過程中,頁面效能可能會被忽略,效能隨著版本迭代而有所衰減;其次,效能優化是一項複雜而挑戰的事情,需要明確的優化方向和具體的優化手段才能快速落地取效。
所以我們需要一個效能監控系統,持續監控和預警頁面效能的狀況,並且在發現瓶頸的時候指導優化工作。
理解Navigation Timing API的效能指標
為了幫助開發者更好地衡量和改進前端頁面效能,W3C效能小組引入了 Navigation Timing API ,實現了自動、精準的頁面效能打點;開發者可以通過 window.performance
屬性獲取。
-
performance.timing
介面(定義了從navigationStart
至loadEventEnd
的 21 個只讀屬性) -
performance.navigation
(定義了當前文件的導航資訊,比如是過載還是向前向後等)
下圖是W3C第一版的 Navigation Timing 的處理模型。從當前瀏覽器視窗解除安裝舊頁面開始,到新頁面載入完成,整個過程一共被切分為 9 個小塊:提示解除安裝舊文件、重定向/解除安裝、應用快取、DNS 解析、TCP 握手、HTTP 請求處理、HTTP 響應處理、DOM 處理、文件裝載完成。每個小塊的首尾、中間做事件分界,取 Unix 時間戳,兩兩事件之間計算時間差,從而獲取中間過程的耗時(精確到毫秒級別)。
上圖是 Level 1 的規範,2012 年底進入候選建議階段,至今仍在日常使用中;但是在W3C的議程上,它已經功成身退,讓位給了精度更高,功能更強大,層次更分明的 Level 2(處理模型如下圖)。比如獨立劃分出來的 Resource Timing,使得我們可以獲取具體資源的詳細耗時資訊。
指標解讀
採集頁面效能的關鍵指標
使用上面的指標,我們可以計算許多重要的指標,如首位元組的時間,頁面載入時間,dns查詢以及連線是否安全。我們把 Navigation Timing API 提供的指標做下歸類,按照從上到下的時間流,右邊的時刻標記了每個指標從哪裡開始計算到哪裡截止,比如,跳轉時間 redirect 由 redirectEnd - redirectStart
計算得到,其他的類推。
確定統計起始點 (navigationStart vs fetchStart )
頁面效能統計的起始點時間,應該是使用者輸入網址回車後開始等待的時間。一個是通過navigationStart
獲取,相當於在URL輸入欄回車或者頁面按F5重新整理的時間點;另外一個是通過 fetchStart
,相當於瀏覽器準備好使用 HTTP 請求獲取文件的時間。
從開發者實際分析使用的場景,瀏覽器重定向、解除安裝頁面的耗時對頁面載入分析並無太大作用;通常建議使用 fetchStart
作為統計起始點。
首位元組
主文件返回第一個位元組的時間,是頁面載入效能比較重要的指標。對使用者來說一般無感知,對於開發者來說,則代表訪問網路後端的整體響應耗時。
白屏時間
使用者看到頁面展示出現一個元素的時間。很多人認為白屏時間是頁面返回的首位元組時間,但這樣其實並不精確,因為頭部資源還沒載入完畢,頁面也是白屏。
相對來說具備「白屏時間」統計意義的指標,可以取 domLoading - fetchStart
,此時頁面開始解析DOM樹,頁面渲染的第一個元素也會很快出現。
從W3C Navigation Timing Level 2 的方案設計,可以直接採用 domInteractive - fetchStart
,此時頁面資源載入完成,即將進入渲染環節。
首屏時間
首屏時間是指頁面第一屏所有資源完整展示的時間。這是一個對使用者來說非常直接的體驗指標,但是對於前端卻是一個非常難以統計衡量的指標。
具備一定意義上的指標可以使用,domContentLoadedEventEnd - fetchStart
,甚至使用loadEventStart - fetchStart
,此時頁面DOM樹已經解析完成並且顯示內容。
以下給出統計頁面效能指標的方法。
let times = {};
let t = window.performance.timing;
// 優先使用 navigation v2 https://www.w3.org/TR/navigation-timing-2/
if (typeof win.PerformanceNavigationTiming === 'function') {
try {
var nt2Timing = performance.getEntriesByType('navigation')[0]
if (nt2Timing) {
t = nt2Timing
}
} catch (err) {
}
}
//重定向時間
times.redirectTime = t.redirectEnd - t.redirectStart;
//dns查詢耗時
times.dnsTime = t.domainLookupEnd - t.domainLookupStart;
//TTFB 讀取頁面第一個位元組的時間
times.ttfbTime = t.responseStart - t.navigationStart;
//DNS 快取時間
times.appcacheTime = t.domainLookupStart - t.fetchStart;
//解除安裝頁面的時間
times.unloadTime = t.unloadEventEnd - t.unloadEventStart;
//tcp連線耗時
times.tcpTime = t.connectEnd - t.connectStart;
//request請求耗時
times.reqTime = t.responseEnd - t.responseStart;
//解析dom樹耗時
times.analysisTime = t.domComplete - t.domInteractive;
//白屏時間
times.blankTime = (t.domInteractive || t.domLoading) - t.fetchStart;
//domReadyTime
times.domReadyTime = t.domContentLoadedEventEnd - t.fetchStart;
複製程式碼
SPA盛行之際
Navigation Timing API可以監控大部分前端頁面的效能。但隨著SPA模式的盛行,類似vue,reactjs等框架的普及,頁面內容渲染的時機被改變了,W3C標準無法完全滿足原來的監控意義。
幸運的是,目前W3C關於首屏統計已經進入了提議階段,以Chrome為首的瀏覽器正在打造更能代表使用者使用體驗的FP、FCP、FMP指標,並且逐步開放API。
注意點
- 通過window.performance.timing所獲的的頁面渲染所相關的資料,在SPA應用中改變了url但不重新整理頁面的情況下是不會更新的。因此僅僅通過該api是無法獲得每一個子路由所對應的頁面渲染的時間。如果需要上報切換路由情況下每一個子頁面重新render的時間,需要自定義上報。
資料上報方式
測量好時間後,就需要將資料傳送給服務端。頁面效能統計資料對丟失率要求比較低,且效能統計應該在儘量不影響主流程的邏輯和頁面效能的前提下進行。
使用的img標籤get請求
-
不存在AJAX跨域問題,可做跨源的請求
-
很古老的標籤,沒有瀏覽器相容性問題
var i = new Image();
i.onload = i.onerror = i.onabort = function () {
i = i.onload = i.onerror = i.onabort = null;
}
i.src = url;
複製程式碼
navigator.sendBeacon
大部分現代瀏覽器都支援 navigator.sendBeacon方法。這個方法可以用來傳送一些統計和診斷的小量資料,特別適合上報統計的場景。
-
資料可靠,瀏覽器關閉請求也照樣能發
-
非同步執行,不會影響下一頁面的載入
-
API使用簡單
window.addEventListener('unload', logData, false);
function logData() {
navigator.sendBeacon("/log", analyticsData);
}
複製程式碼
最終方案
當瀏覽器支援sendBeacon方法,優先使用該方法,使用img方式降級上報。
嶽鷹-WEB前端監控
經過1年左右時間的不斷打磨,阿里UC出品的嶽鷹WEB前端監控已經對外開放,歡迎免費體驗試用。
技術交流、第一時間掌握產品動態,歡迎聯絡我們~
聯絡微信小助手(微訊號 effirst-assistant)
加入釘釘群討論(群號21964256)
參考
navigation-timing-2 www.w3.org/TR/navigati…
Navigation API指南 s0developer0mozilla0org.icopy.site/en-US/docs/…
以使用者為中心的效能指標 developers.google.com/web/fundame…
頁面效能對業務指標的影響 www.thinkwithgoogle.com/marketing-r…