天天看點

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

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

前言

前端頁面性能是一個非常核心的使用者體驗名額。本文介紹阿裡UC

嶽鷹全景監控平台

如何設計一個通用、低侵入性、自動上報的頁面性能監控方案。主要采用的是Navigation Timing API以及sendBeacon等方法。

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

為什麼要監控頁面性能?

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

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

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

了解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 時間戳,兩兩事件之間計算時間差,進而擷取中間過程的耗時(精确到毫秒級别)。

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

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

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

名額解讀

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

采集頁面性能的關鍵名額

使用上面的名額,我們可以計算許多重要的名額,如

首位元組的時間

,頁面加載時間,dns查找以及連接配接是否安全。我們把 Navigation Timing API 提供的名額做下歸類,按照從上到下的時間流,右邊的時刻标記了每個名額從哪裡開始計算到哪裡截止,比如,跳轉時間 redirect 由

redirectEnd - redirectStart

計算得到,其他的類推。

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

确定統計起始點 (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。

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

注意點

  • 通過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前端監控

已經對外開放,歡迎免費體驗試用。

參考

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/

繼續閱讀