前端錯誤監控與收集探究

編寫代碼只是作好項目的一小部分,寫代碼不免會碰到錯誤。所以,在項目上線後,咱們還須要主動對項目的錯誤進行收集,不能等用戶發現錯誤,再聯繫咱們,咱們再去處理。這樣很容易形成大的損失,提早作好錯誤收集和處理,能夠減小損失。html

本人並無作過相關的工做,下面的文章只是我在學習中的一點思考和總結,可能有比較多不足和錯誤的地方,但願你們指正和指導。前端

本文章爲前端進階系列的一部分,
歡迎關注和star本博客或是關注個人githubgit

收集哪些錯誤信息

先從一個面試題開始吧。騰訊第二輪電話面試的一個題目:若是用戶使用網頁,發現白屏,如今聯繫上了大家,大家會向他詢問什麼信息呢?github

<!-- more -->
一個個去堆答案沒有意思,咱們換個思路,先想一下爲何會白屏?web

錯誤發生在什麼環節

跟我以前的性能優化的文章同樣,咱們以用戶訪問頁面的過程爲順序,大體排查一下面試

  1. 用戶沒打開網絡
  2. DNS域名劫持
  3. http劫持
  4. cdn或是其餘資源文件訪問出錯
  5. 服務器錯誤
  6. 前端代碼錯誤
  7. 前端兼容性問題
  8. 用戶操做出錯

收集哪些信息

經過以上可能發生錯誤的環節,咱們須要向用戶手機一下如下的用戶信息ajax

  1. 當前的網絡狀態
  2. 運營商
  3. 地理位置
  4. 訪問時間
  5. 客戶端的版本(若是是經過客戶端訪問)
  6. 系統版本
  7. 瀏覽器信息
  8. 設備分辨率
  9. 頁面的來源
  10. 用戶的帳號信息
  11. 經過performance API收集用戶各個頁面訪問流程所消耗的時間,看錯誤出如今什麼環節
  12. 收集用戶js代碼報錯的信息

如何收集錯誤的信息

如今話題來到了如何收集錯誤信息了。chrome

前端錯誤收集有兩大流派:後端

一個是虛擬機監控,優勢是指標齊全,而且能夠進行競品監控,缺點是反映不全,容易失真跨域

另外一個是腳本監控,優勢是能夠收集海量真實數據,缺點是影響性能,採樣少的狀況下容易失真。

這裏暫時只講腳本監控(挖個坑,以後可能填)

訪問時間記錄

performance API

在chrome瀏覽器控制檯輸入Performance.timing,會獲得記錄了一個瀏覽器訪問各階段的時間的對象。

進行錯誤收集的時候,能夠對比這些時間,看錯誤發生在什麼階段

  1. DNS 查詢耗時 :domainLookupEnd - domainLookupStart
  2. TCP 連接耗時 :connectEnd - connectStart
  3. request 請求耗時 :responseEnd - responseStart
  4. 解析 dom 樹耗時 : domComplete - domInteractive
  5. 白屏時間 :responseStart - navigationStart
  6. domready 時間 :domContentLoadedEventEnd - navigationStart
  7. onload 時間 :loadEventEnd – navigationStart

其餘方法

記錄訪問開始的時間可有如下的方法:

  1. 服務器將訪問的時間渲染到頁面上
  2. SPA的話,記錄前一個頁面卸載的時間

記錄訪問過程的時間

  1. 在head標籤解析後,渲染body標籤前加入script標籤進行打點,通常將這個時間視爲白屏時間
  2. 捕獲DOMContentLoaded事件來記錄dom元素加載完畢的時間
  3. 在首屏頁面的全部圖片加載完後進行記錄,保存首屏時間
  4. 捕獲load事件記錄頁面加載完成的時間

腳本錯誤收集

window.onerror

window.onerror能夠捕捉運行時錯誤,能夠拿到出錯的信息,堆棧,出錯的文件、行號、列號

要注意如下幾點:

  1. 要把window.onerror這個代碼塊分離出去,而且比其餘腳本先執行(注意這個前提!)便可捕捉到語法錯誤。
  2. 因爲網絡請求異常事件不會冒泡,須要在捕獲階段進行處理
  3. 不能捕獲promise的錯誤信息
  4. 跨域資源須要專門處理,須要在script標籤加上crossorigin屬性,服務器設置Access-Control-Allow-Origin
  5. window.onerror 函數只有在返回 true 的時候,異常纔不會向上拋出,不然即便是知道異常的發生控制檯仍是會顯示 Uncaught Error: xxxxx。

promise的錯誤處理

promise除了使用catch方法來捕獲錯誤,還可使用window的unhandledrejection事件捕獲異常的

window.addEventListener("unhandledrejection", function(e){
  // Event新增屬性
  // @prop {Promise} promise - 狀態爲rejected的Promise實例
  // @prop {String|Object} reason - 異常信息或rejected的內容

  // 會阻止異常繼續拋出,不讓Uncaught(in promise) Error產生
  e.preventDefault()
})

try catch

沒法捕捉到語法錯誤,只能捕捉運行時錯誤;
能夠拿到出錯的信息,堆棧,出錯的文件、行號、列號; 須要藉助工具把全部的function塊以及文件塊加入try,catch,能夠在這個階段打入更多的靜態信息。

要注意的是try catch只能捕獲同步代碼的異常,對回調,setTimeout,promise等無能爲力

上報錯誤的方式

  1. 後端提供接口,前端ajax上傳
  2. 建立一個新的圖片,url參數帶上錯誤信息
function report(error) {
  var reportUrl = 'http://xxxx/report';
  new Image().src = reportUrl + 'error=' + error;
}

最後

本文章爲前端進階系列的一部分,
歡迎關注和star本博客或是關注個人github

參考

  1. 前端魔法堂——異常不只僅是try/catch
  2. 前端優化-如何計算白屏和首屏時間
相關文章
相關標籤/搜索