需求調(diào)研
最近有接手一個(gè)新項(xiàng)目需要獲取一系列的性能指標(biāo):建連時(shí)間? ssl握手時(shí)長(zhǎng) 首包時(shí)間? 首屏?xí)r間? 下載時(shí)長(zhǎng)? 下載總時(shí)間? 下載速率? ,需要模擬一系列的測(cè)試場(chǎng)景:需要對(duì)比1k,10k,100k,1m,10m,100m需要對(duì)比視頻流播放,需要對(duì)比文件下載,需要對(duì)比多路重傳
手工測(cè)試方案:使用chrome的dev tool查看記錄數(shù)據(jù)



解決方案:
1、獲取性能指標(biāo):
使用window.performance.timing API
(https://developer.mozilla.org/zh-CN/docs/Web/API/PerformanceTiming)

PerformanceTiming.navigationStart 只讀
是一個(gè)無(wú)符號(hào)long long 型的毫秒數(shù),表征了從同一個(gè)瀏覽器上下文的上一個(gè)文檔卸載(unload)結(jié)束時(shí)的UNIX時(shí)間戳。如果沒(méi)有上一個(gè)文檔,這個(gè)值會(huì)和PerformanceTiming.fetchStart相同。
PerformanceTiming.unloadEventStart 只讀
是一個(gè)無(wú)符號(hào)long long 型的毫秒數(shù),表征了unload事件拋出時(shí)的UNIX時(shí)間戳。如果沒(méi)有上一個(gè)文檔,or if the previous document, or one of the needed redirects, is not of the same origin, 這個(gè)值會(huì)返回0.
PerformanceTiming.unloadEventEnd 只讀
是一個(gè)無(wú)符號(hào)long long 型的毫秒數(shù),表征了unload事件處理完成時(shí)的UNIX時(shí)間戳。如果沒(méi)有上一個(gè)文檔,or if the previous document, or one of the needed redirects, is not of the same origin, 這個(gè)值會(huì)返回0.
PerformanceTiming.redirectStart 只讀
是一個(gè)無(wú)符號(hào)long long 型的毫秒數(shù),表征了第一個(gè)HTTP重定向開始時(shí)的UNIX時(shí)間戳。如果沒(méi)有重定向,或者重定向中的一個(gè)不同源,這個(gè)值會(huì)返回0.
PerformanceTiming.redirectEnd 只讀
是一個(gè)無(wú)符號(hào)long long 型的毫秒數(shù),表征了最后一個(gè)HTTP重定向完成時(shí)(也就是說(shuō)是HTTP響應(yīng)的最后一個(gè)比特直接被收到的時(shí)間)的UNIX時(shí)間戳。如果沒(méi)有重定向,或者重定向中的一個(gè)不同源,這個(gè)值會(huì)返回0.
PerformanceTiming.fetchStart 只讀
是一個(gè)無(wú)符號(hào)long long 型的毫秒數(shù),表征了瀏覽器準(zhǔn)備好使用HTTP請(qǐng)求來(lái)獲取(fetch)文檔的UNIX時(shí)間戳。這個(gè)時(shí)間點(diǎn)會(huì)在檢查任何應(yīng)用緩存之前。
PerformanceTiming.domainLookupStart 只讀
是一個(gè)無(wú)符號(hào)long long 型的毫秒數(shù),表征了域名查詢開始的UNIX時(shí)間戳。如果使用了持續(xù)連接(persistent connection),或者這個(gè)信息存儲(chǔ)到了緩存或者本地資源上,這個(gè)值將和 PerformanceTiming.fetchStart一致。
PerformanceTiming.domainLookupEnd 只讀
是一個(gè)無(wú)符號(hào)long long 型的毫秒數(shù),表征了域名查詢結(jié)束的UNIX時(shí)間戳。如果使用了持續(xù)連接(persistent connection),或者這個(gè)信息存儲(chǔ)到了緩存或者本地資源上,這個(gè)值將和 PerformanceTiming.fetchStart一致。
PerformanceTiming.connectStart 只讀
是一個(gè)無(wú)符號(hào)long long 型的毫秒數(shù),返回HTTP請(qǐng)求開始向服務(wù)器發(fā)送時(shí)的Unix毫秒時(shí)間戳。如果使用持久連接(persistent connection),則返回值等同于fetchStart屬性的值。
PerformanceTiming.connectEnd 只讀
是一個(gè)無(wú)符號(hào)long long 型的毫秒數(shù),返回瀏覽器與服務(wù)器之間的連接建立時(shí)的Unix毫秒時(shí)間戳。如果建立的是持久連接,則返回值等同于fetchStart屬性的值。連接建立指的是所有握手和認(rèn)證過(guò)程全部結(jié)束。
PerformanceTiming.secureConnectionStart 只讀
是一個(gè)無(wú)符號(hào)long long 型的毫秒數(shù),返回瀏覽器與服務(wù)器開始安全鏈接的握手時(shí)的Unix毫秒時(shí)間戳。如果當(dāng)前網(wǎng)頁(yè)不要求安全連接,則返回0。
PerformanceTiming.requestStart 只讀
是一個(gè)無(wú)符號(hào)long long 型的毫秒數(shù),返回瀏覽器向服務(wù)器發(fā)出HTTP請(qǐng)求時(shí)(或開始讀取本地緩存時(shí))的Unix毫秒時(shí)間戳。
PerformanceTiming.responseStart 只讀
是一個(gè)無(wú)符號(hào)long long 型的毫秒數(shù),返回瀏覽器從服務(wù)器收到(或從本地緩存讀?。┑谝粋€(gè)字節(jié)時(shí)的Unix毫秒時(shí)間戳。如果傳輸層在開始請(qǐng)求之后失敗并且連接被重開,該屬性將會(huì)被數(shù)制成新的請(qǐng)求的相對(duì)應(yīng)的發(fā)起時(shí)間。
PerformanceTiming.responseEnd 只讀
是一個(gè)無(wú)符號(hào)long long 型的毫秒數(shù),返回瀏覽器從服務(wù)器收到(或從本地緩存讀取,或從本地資源讀?。┳詈笠粋€(gè)字節(jié)時(shí)(如果在此之前HTTP連接已經(jīng)關(guān)閉,則返回關(guān)閉時(shí))的Unix毫秒時(shí)間戳。
PerformanceTiming.domLoading 只讀
是一個(gè)無(wú)符號(hào)long long 型的毫秒數(shù),返回當(dāng)前網(wǎng)頁(yè)DOM結(jié)構(gòu)開始解析時(shí)(即Document.readyState屬性變?yōu)椤發(fā)oading”、相應(yīng)的 readystatechange事件觸發(fā)時(shí))的Unix毫秒時(shí)間戳。
PerformanceTiming.domInteractive 只讀
是一個(gè)無(wú)符號(hào)long long 型的毫秒數(shù),返回當(dāng)前網(wǎng)頁(yè)DOM結(jié)構(gòu)結(jié)束解析、開始加載內(nèi)嵌資源時(shí)(即Document.readyState屬性變?yōu)椤癷nteractive”、相應(yīng)的readystatechange事件觸發(fā)時(shí))的Unix毫秒時(shí)間戳。
PerformanceTiming.domContentLoadedEventStart 只讀
是一個(gè)無(wú)符號(hào)long long 型的毫秒數(shù),返回當(dāng)解析器發(fā)送DOMContentLoaded 事件,即所有需要被執(zhí)行的腳本已經(jīng)被解析時(shí)的Unix毫秒時(shí)間戳。
PerformanceTiming.domContentLoadedEventEnd 只讀
是一個(gè)無(wú)符號(hào)long long 型的毫秒數(shù),返回當(dāng)所有需要立即執(zhí)行的腳本已經(jīng)被執(zhí)行(不論執(zhí)行順序)時(shí)的Unix毫秒時(shí)間戳。
PerformanceTiming.domComplete 只讀
是一個(gè)無(wú)符號(hào)long long 型的毫秒數(shù),返回當(dāng)前文檔解析完成,即Document.readyState 變?yōu)?'complete'且相對(duì)應(yīng)的``readystatechange 被觸發(fā)時(shí)的Unix毫秒時(shí)間戳。
PerformanceTiming.loadEventStart 只讀
是一個(gè)無(wú)符號(hào)long long 型的毫秒數(shù),返回該文檔下,load事件被發(fā)送時(shí)的Unix毫秒時(shí)間戳。如果這個(gè)事件還未被發(fā)送,它的值將會(huì)是0。
PerformanceTiming.loadEventEnd 只讀
是一個(gè)無(wú)符號(hào)long long 型的毫秒數(shù),返回當(dāng)load事件結(jié)束,即加載事件完成時(shí)的Unix毫秒時(shí)間戳。如果這個(gè)事件還未被發(fā)送,或者尚未完成,它的值將會(huì)是0.
自動(dòng)化:puppeteer支持chrome devtool protocol獲取協(xié)議名稱
(https://chromedevtools.github.io/devtools-protocol/)

調(diào)用過(guò)程

使用tracing api獲取性能指標(biāo)
開啟,關(guān)閉tracing:

解析tracing:

2、性能數(shù)據(jù)入庫(kù)
nodejs+sqlite3方案;

數(shù)據(jù):

3、可視化展示
Django+layui+echarts

使用puppteer測(cè)試框架,基于它對(duì)chrome的良好支持,可以把很多chrome調(diào)試的手工工作實(shí)現(xiàn)自動(dòng)化,大家對(duì)puppeteer有什么妙用呢?歡迎回復(fù)和討論!