一、前端監控是監控什么?
一是監控用戶的行為,比如說頁面的入口來源、點擊量、瀏覽量、頁面停留時長等。通過對用戶的行為數據進行分析,可以對我們的產品進行針對性的優化。比如說用戶在哪個頁面停留時間較長,我們便可以在這個頁面進行我們的廣告投放等;
二是監控頁面的性能,比如說頁面的白屏時長,首屏時長、接口請求快慢等。由於每個用戶的手機型號、網絡情況等的不同,我們開發時是沒法明確知道頁面的性能如何的,所以需要統計這些數據,對我們的頁面進行相應的優化。頁面加載時長越慢可能流失的用戶就越多,沒有人願意去長時間等待一個卡頓的頁面。
三是監控頁面的異常,比如說弱網情況下某些文件加載失敗、某些特定情況下才會出現的業務bug、頁面的兼容bug、內存泄漏等,這些在測試階段可能沒辦法都檢測出來,所以需要對我們頁面的錯誤進行監控,這點是很重要的。
二、怎么進行前端監控?
對我們的頁面進行監控,那么我們就需要在我們的頁面里進行埋點。什么是埋點呢?
埋點,它的學名是事件追蹤(
Event Tracking
),主要是針對特定用戶行為或業務過程進行捕獲、處理和發送的相關技術及實施過程。埋點是數據領域的一個專業術語,也是互聯網領域的一個俗稱。埋點是產品數據分析的基礎,一般用於推薦系統的反饋、用戶行為的監控和分析、新功能或者運營活動效果的統計分析等。
簡言之,就是需要在我們的頁面里加上特定的代碼進行數據的收集,然后提交給后台去進行分析。
那么埋點有哪些方案呢?
三、埋點方案
手動埋點
手動埋點也叫代碼埋點,也就是在我們的代碼里加上特定的代碼上傳數據給到后端或者說調用相應SDK的函數,常見的網站分析工具有很多,國內一般常用的有神策等,國外常用的有Google Analytics
等。手動埋點的好處有可以讓使用者很方便的設置自定義屬性,自定義事件,只對自己需要的數據進行埋點,后續無需對大量的數據進行篩選。但是由於需要開發人員一一在代碼中加入埋點,項目工程量比較大,且容易出現漏埋、錯埋等情況。
埋點數據發送可以通過接口上報,也可以通過img/iframe/script
上報。一般采用img
標簽的src
屬性進行發送,如下:
let baseURL = 'https://www......'
let queryStr = Object.entries(query).map(([key, value]) => `${key}=${value}`).join('&')
let img = new Image();
img.src = `${baseURL}?${queryStr}`
采用img
的src
屬性發送的原因有下:
- 沒有跨域的限制,像srcipt標簽、img標簽都可以直接發送跨域的GET請求,不用做特殊處理。
- 兼容性好,不需要插入DOM,影響頁面性能。
后端一般會返回一張1px * 1px大小的GIF圖片。同樣大小,不同格式的圖片中GIF的大小是最小的。
可視化埋點
可視化埋點即以業務代碼為輸入,通過可視化系統配置埋點,最后以耦合的形式輸出業務代碼和埋點代碼,但是可視化系統的埋點控件有限,並不能充分滿足埋點需求。
可視化埋點的流程通常為:
輸入頁面的url => 頁面加載完成后 => 配置可視化的工具 => 點擊創建事件(click) => 進入元素選擇模式 => 用鼠標點擊頁面上的某個元素(例如button、a這些element)=> 就可以在彈出的對話框里面 => 設置這個事件的名稱(比如叫TEST),選上報數據屬性(properties)=> 保存配置 => 用戶訪問點擊按鈕 => 數據上報
無埋點
無埋點則是前端自動采集全部事件,上報埋點數據,由后端來過濾和計算出有用的數據。優點是前端只要一次加載埋點腳本,不會出現漏埋、錯埋等情況。缺點是流量和采集的數據過於龐大,服務器性能壓力大。
四、錯誤監控
頁面的用戶行為監控及頁面性能監控可能不是必須的,但是錯誤監控是所有的頁面必須的。那么怎么對頁面進行錯誤監控呢?
頁面中的代碼建議都加上try/catch
,它能捕獲常規運行錯誤,但是語法錯誤和異步錯誤不行。
try {
console.log(notdefined);
} catch(e) {
console.log('捕獲到異常:', e);
}
window.onerror
能捕獲常規運行錯誤,異步錯誤也可捕獲,但是不能捕獲語法錯誤及資源加載錯誤。
window.onerror = function(message, source, lineno, colno, error) {
console.log('捕獲到異常:',{message, source, lineno, colno, error});
}
console.log(notdefined);
window.addEventListener
能捕獲常規運行錯誤、異步錯誤及資源加載錯誤,但是不能捕獲語法錯誤、new Image錯誤及fetch錯誤。
window.addEventListener('error', (error) => {
console.log('捕獲到異常:', error);
}, true)
以上方法都不能捕獲promise
類型的錯誤,要捕獲promise
類型的錯誤需要通過unhandledrejection
捕獲。
window.addEventListener("unhandledrejection", function(e){
console.log('捕獲到異常:', e);
});
由於Vue會捕獲所有Vue單文件組件或者Vue.extend繼承的代碼,所以在Vue里面出現的錯誤,並不會直接被window.onerror捕獲,而是會拋給Vue.config.errorHandler。
Vue.config.errorHandler = function (err) {
setTimeout(() => {
throw err
})
}
五、參考文章
1、騰訊二面:現在要你實現一個埋點監控SDK,你會怎么設計?
2、為什么大廠前端監控都在用GIF做埋點?
3、去大廠,你就應該了解前端監控和埋點!
4、miracle90/monitor
5、前端埋點總結
6、一篇講透自研的前端錯誤監控