起因
最近接觸到了一個性能優化方面為我們提供精準數據的工具,Navigation Timing,本想從網上獲取他更詳細的信息,但搜索到的內容絕大部分都是國外的文章,遂決定寫一遍具體分析的文章。
之前測試頁面加載的時間都是在相應的位置打Date.now(),通過計算時間差來實現。這樣的做法有很多弊端。
- 需要在許多地方添加額外的代碼
- 記錄的時間不準確
- 測試完之后需要找到每一個地方注釋or刪除,容易落下且麻煩
W3C Web Performance Working Group 引入了 Navigation Timing API 幫我們自動,精準的實現了性能測試的打點問題。
Navigation Timing API 用法
用法很簡單,在頁面load完之后我們可以從performance.timing對象中拿到我們需要的所有數據。見下圖:
Navigation Timing不僅幫我們省去了繁瑣的手動打點的操作,而且提供了以前我們無法獲取到的數據,比如DNS和TCP連接所需的時間。
里面提供的具體事件如下圖:
參數說明
具體文字說明:
- navigationStart
加載起始時間 - redirectStart
重定向開始時間(如果發生了HTTP重定向,每次重定向都和當前文檔同域的話,就返回開始重定向的fetchStart的值。其他情況,則返回0) - redirectEnd
重定向結束時間(如果發生了HTTP重定向,每次重定向都和當前文檔同域的話,就返回最后一次重定向接受完數據的時間。其他情況則返回0) - fetchStart
瀏覽器發起資源請求時,如果有緩存,則返回讀取緩存的開始時間 - domainLookupStart
查詢DNS的開始時間。如果請求沒有發起DNS請求,如keep-alive,緩存等,則返回fetchStart - domainLookupEnd
查詢DNS的結束時間。如果沒有發起DNS請求,同上 - connectStart
開始建立TCP請求的時間。如果請求是keep-alive,緩存等,則返回domainLookupEnd - (secureConnectionStart)
如果在進行TLS或SSL,則返回握手時間 - connectEnd
完成TCP鏈接的時間。如果是keep-alive,緩存等,同connectStart - requestStart
發起請求的時間 - responseStart
服務器開始響應的時間 - domLoading
從圖中看是開始渲染dom的時間,具體未知 - domInteractive
未知 - domContentLoadedEventStart
開始觸發DomContentLoadedEvent事件的時間 - domContentLoadedEventEnd
DomContentLoadedEvent事件結束的時間 - domComplete
從圖中看是dom渲染完成時間,具體未知 - loadEventStart
觸發load的時間,如沒有則返回0 - loadEventEnd
load事件執行完的時間,如沒有則返回0 - unloadEventStart
unload事件觸發的時間 - unloadEventEnd
unload事件執行完的時間
注,從domLoading開始往下的參數chrome官網并未給出具體英文解釋,只是猜測,如有錯誤,歡迎糾正。
附上官方鏈接
簡單用法
這些參數已經非常詳細,也很精準,稍作處理就可以得出我們需要的一些關鍵數字,如:
- DNS解析時間: domainLookupEnd - domainLookupStart
- TCP建立連接時間: connectEnd - connectStart
- 白屏時間: responseStart - navigationStart
- dom渲染完成時間: domContentLoadedEventEnd - navigationStart
- 頁面onload時間: loadEventEnd - navigationStart
demo如下:
let timing = performance.timing,
start = timing.navigationStart,
dnsTime = 0,
tcpTime = 0,
firstPaintTime = 0,
domRenderTime = 0,
loadTime = 0;
dnsTime = timing.domainLookupEnd - timing.domainLookupStart;
tcpTime = timing.connectEnd - timing.connectStart;
firstPaintTime = timing.responseStart - start;
domRenderTime = timing.domContentLoadedEventEnd - start;
loadTime = timing.loadEventEnd - start;
console.log('DNS解析時間:', dnsTime , '\nTCP建立時間:', tcpTime, '\n首屏時間:', firstPaintTime,
'\ndom渲染完成時間:', domRenderTime, '\n頁面onload時間:', loadTime);
效果如下:
兼容性
目前Navigation Timing已經普及,絕大部分主流瀏覽器都已經支持
那么,開始優化你的app吧
3Fuyu