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