10分鐘徹底搞懂前端頁面性能監控

本文首發於知乎《10分鐘徹底搞懂前端頁面性能監控》,搬運轉載請註明出處,否則追究版權責任。

前言

前端頁面性能是一個非常核心的用戶體驗指標。本文介紹 嶽鷹全景監控平臺 如何設計一個通用、低侵入性、自動上報的頁面性能監控方案。主要採用的是Navigation Timing API以及sendBeacon等方法。

導讀

爲什麼要監控頁面性能?

一個頁面性能差的話會大大影響用戶體驗。用戶打開頁面等待的太久,可能會直接關掉頁面,甚至就不再使用了,這種情況在移動端更加明顯,移動端用戶對頁面響應延遲容忍度很低。

雖然頁面性能很重要,但是在實際使用中,頁面性能差的情況並不少見。首先,在產品的迭代演進過程中,頁面性能可能會被忽略,性能隨着版本迭代而有所衰減;其次,性能優化是一項複雜而挑戰的事情,需要明確的優化方向和具體的優化手段才能快速落地取效。

所以我們需要一個性能監控系統,持續監控和預警頁面性能的狀況,並且在發現瓶頸的時候指導優化工作。

理解Navigation Timing API的性能指標

爲了幫助開發者更好地衡量和改進前端頁面性能,W3C性能小組引入了 Navigation Timing API ,實現了自動、精準的頁面性能打點;開發者可以通過 window.performance 屬性獲取。

  • performance.timing 接口(定義了從 navigationStartloadEventEnd 的 21 個只讀屬性)
  • performance.navigation(定義了當前文檔的導航信息,比如是重載還是向前向後等)

下圖是W3C第一版的 Navigation Timing 的處理模型。從當前瀏覽器窗口卸載舊頁面開始,到新頁面加載完成,整個過程一共被切分爲 9 個小塊:提示卸載舊文檔、重定向/卸載、應用緩存、DNS 解析、TCP 握手、HTTP 請求處理、HTTP 響應處理、DOM 處理、文檔裝載完成。每個小塊的首尾、中間做事件分界,取 Unix 時間戳,兩兩事件之間計算時間差,從而獲取中間過程的耗時(精確到毫秒級別)。

W3C Navigation Timing Level 1

上圖是 Level 1 的規範,2012 年底進入候選建議階段,至今仍在日常使用中;但是在W3C的議程上,它已經功成身退,讓位給了精度更高,功能更強大,層次更分明的 Level 2(處理模型如下圖)。比如獨立劃分出來的 Resource Timing,使得我們可以獲取具體資源的詳細耗時信息。

W3C Navigation Timing Level 2

指標解讀

指標

採集頁面性能的關鍵指標

使用上面的指標,我們可以計算許多重要的指標,如首字節的時間,頁面加載時間,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方式降級上報。

參考

navigation-timing-2 https://www.w3.org/TR/navigation-timing-2/

Navigation API指南 https://s0developer0mozilla0org.icopy.site/en-US/docs/Web/Performance/Navigation_and_resource_timings

以用戶爲中心的性能指標 https://developers.google.com/web/fundamentals/performance/user-centric-performance-metrics?hl=zh-cn

頁面性能對業務指標的影響 https://www.thinkwithgoogle.com/marketing-resources/data-measurement/mobile-page-speed-new-industry-benchmarks/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章