如何收集前端頁面性能參數(shù)
點擊上方 程序員成長指北,關(guān)注公眾號
回復(fù)1,加入高級 Node 進(jìn)階交流群
一、請求時間統(tǒng)計

上圖是performance.timing監(jiān)測到的特定于用戶的計時器,通過這些屬性的組合搭配,可以獲取到特定的時間數(shù)據(jù)。
垂直角度的度量順序圖:

1)performance
設(shè)置好插件中全局的performance對象,以及方法now,獲取當(dāng)前時間戳。

2)Document.readyState
上圖中的“domComplete”、“domInteractive”和“domLoading”,就是Document。readyState的3種狀態(tài)loading, interactive或complete發(fā)生的時間。



3)getTimes()
在這個方法中計算各個參數(shù)之間的值。
在網(wǎng)上參考了很多資料,再結(jié)合了一點自己的理解,有些參數(shù)的理解可能有誤,具體的計算方式可以查看源碼“primus.js”。
firstPaint:白屏?xí)r間,也就是開始解析DOM耗時,用戶在沒有滾動時候看到的內(nèi)容渲染完成并且可以交互的時間
loadTime:加載總時間,這幾乎代表了用戶等待頁面可用的時間
unloadEventTime:Unload事件耗時
loadEventTime:執(zhí)行 onload 回調(diào)函數(shù)的時間
domReadyTime:用戶可操作時間
firstScreen:首屏?xí)r間,用戶在沒有滾動時候看到的內(nèi)容渲染完成并且可以交互的時間,記錄載入時間最長的圖片
parseDomTime:解析 DOM 樹結(jié)構(gòu)的時間,期間要加載內(nèi)嵌資源
initDomTreeTime:請求完畢至DOM加載耗時
readyStart:準(zhǔn)備新頁面時間耗時
redirectTime:重定向的時間
appcacheTime:DNS緩存耗時
lookupDomainTime:DNS查詢耗時
connectTime:TCP連接耗時
requestTime:內(nèi)容加載完成的時間
requestDocumentTime:請求文檔時間,開始請求文檔到開始接收文檔
responseDocumentTime:接收文檔時間,開始接收文檔到文檔接收完成
TTFB(Time To First Byte):讀取頁面第一個字節(jié)的時間
二、資源載入信息
performance對象中有個getEntries方法,通過此方法可以將頁面中的資源載入情況記錄下來。
可以繪制出像下圖那樣的瀑布圖。

然而此方法兼容性非常差,我在紅米手機中測試,UC不行,自帶的瀏覽器倒是可以將信息打印出來。
在插件中也稍微封裝了一個方法“getEntries”,在兼容的瀏覽器中可以采集到相關(guān)數(shù)據(jù)。
name:資源的完整路徑,例如“http://localhost:63342/web/strick/Primus/ajax/data2.json”
fileName:文件名。例如“data2.json”
duration:資源載入總共消耗的時間
requestStartDelay:開始請求延時時間
lookupDomainTime:DNS 查詢時間
connectTime:TCP 建立連接完成握手的時間
TTFB:讀取資源第一個字節(jié)的時間
requestTime:內(nèi)容加載完成的時間
requestDuration:請求區(qū)間
redirectTime:重定向的時間
在一些商業(yè)性能采集的應(yīng)用中,我看到有瀑布圖的展示,不知道他們是怎么搞的。
三、網(wǎng)絡(luò)狀態(tài)
網(wǎng)絡(luò)狀況 API“navigator.connection”也是個很有用的參數(shù),然而兼容性也是非常差。
網(wǎng)絡(luò)狀態(tài)就是獲取當(dāng)前是“WIFI 2G 3G 4G”等。
如果能獲取到這個參數(shù),就能準(zhǔn)確知道頁面在不同網(wǎng)絡(luò)狀態(tài)中展現(xiàn)的情況。
四、網(wǎng)速
沒有專門的API提供當(dāng)前用戶的網(wǎng)速,但可以通過下載某個大文件來計算。
目前只知道這種方法,感覺實用性不是很大。
在index.html中寫了個例子,將圖片放到某個服務(wù)器下面會更準(zhǔn)確一些。


五、AJAX監(jiān)控
現(xiàn)在的頁面上面充斥著大量的ajax請求,可以將請求的信息保存起來有助于分析性能。
在項目中使用Zepto庫、jQuery等封裝好的庫,最后還是會調(diào)用原生的“XMLHttpRequest”
可以重新一下“XMLHttpRequest”對象,在這個對象的幾個步驟中埋入要統(tǒng)計的點。
window.XMLHttpRequest = function(flags) {
var req;
// 調(diào)用原生的XMLHttpRequest
req = new _XMLHttpRequest(flags);
// 埋入我們的“間諜”
monitorXHR(req);
return req;
};
在open和send中也埋入統(tǒng)計的方法,通過這種方式就能獲取到信息了,下圖就是統(tǒng)計的信息。

六、UA信息和分辨率
1)UA信息
每個請求頭中都會帶有“User-Agent”屬性,通過這個屬性可以分析出OS、Device、Browser、Platform等信息。

我自己沒有封裝這個頭,網(wǎng)上有很多插件可以做分析的工作,不過JS的話有點大。
國外有“UAParser.js”,關(guān)注量1400多了,不過簡單測試下來,對于國內(nèi)手機的分析不是很給力,如果要用的話還得自己修改下源碼。
國內(nèi)有“useragent”,有js和php多個版本,小測了一下,國內(nèi)手機辨別率還挺高的。

2)分辨率
這個比較簡單就是獲取屏幕的物理寬度和高度,一句話就能獲取。
primus.dpi = function() {
return {width:window.screen.width, height:window.screen.height};
};
七、異常監(jiān)控
異常監(jiān)控就是監(jiān)聽“window.onerror”事件,在這個事件內(nèi)能夠獲取到錯誤提示信息,行數(shù),列數(shù),錯誤地址。
/**
* 異常監(jiān)控
* https://github.com/BetterJS/badjs-report
* @param {String} msg 錯誤信息
* @param {String} url 出錯文件的URL
* @param {Long} line 出錯代碼的行號
* @param {Long} col 出錯代碼的列號
* @param {Object} error 錯誤信息Object https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Error
*/
window.onerror = function(msg, url, line, col, error) {
var newMsg = msg;
if (error && error.stack) {
var stack = error.stack.replace(/\n/gi, "").split(/\bat\b/).slice(0, 9).join("@").replace(/\?[^:]+/gi, "");
var msg = error.toString();
if (stack.indexOf(msg) < 0) {
stack = msg + "@" + stack;
}
newMsg = stack;
}
var obj = {msg:newMsg, target:url, rowNum:line, colNum:col};
alert(obj.msg);
};
八、數(shù)據(jù)發(fā)送與引用
1)數(shù)據(jù)發(fā)送
為了更好的跨域,數(shù)據(jù)發(fā)送通過設(shè)置Image對象的src來實現(xiàn)。
簡單的將各個收集過來的數(shù)據(jù)作為URL中的參數(shù)傳過去,代碼中可能有BUG。

發(fā)送以后就是保存數(shù)據(jù)了,可以將數(shù)據(jù)保存在Hadoop中。
2)Primus的引用
由于要計算白屏?xí)r間,dom時間等,所以位置不能隨便放,得要放在head的最后面。
如果要做點初始化配置也是完全OK的。
<head>
<script type='text/javascript'>
window.primus || (primus={});
primus.param = {
"token":"dsadasd2323dsad23dsada",
"backgroundImages":[]
};
</script>
<script src="js/primus.js"></script>
</head>
end
最后


“分享、點贊、在看” 支持一波
