開發與維運

為你的前端頁面量身打造一套實時監控指標

背景

今年年初,我進入一個基於React開發的新項目,負責整個前端的開發工作。為了保證整體的質量和用戶體驗,我們需要在項目上線時對應用進行穩定性和性能監控,確保線上發現異常時能夠被第一時間發現和解決。

工欲善其事,必先利其器,這時候我們需要一個好輪子。對於前端頁面的監控,通常包括頁面的訪問性能、頁面JS錯誤、資源加載錯誤,以及後端API的請求情況。

UC研發效能團隊有一個叫做【嶽鷹】的WEB高可用監控產品,支持H5、小程序、Flutter監控,監控指標比較齊全,而且支持線上海量訪問的實時監控,於是決定試用一把。

下面我就講講我怎麼在新項目裡面設定業務的性能/體驗指標,並且通過監控工具來分析、優化最終達成目標。

Step01,一行代碼搞定前端監控

體驗【嶽鷹】的Demo項目,大概瞭解嶽鷹提供的監控和分析功能,我比較關心的功能都具備:

  • 頁面性能監控,而且支持性能趨勢 + 性能數據樣本分佈,對於分析長尾的慢訪問比較有幫助
  • JS錯誤監控,並且支持source map還原,查看線上混淆的錯誤代碼很方便
  • API錯誤監控,很多時候接口錯誤也會導致前端報錯,支持API錯誤碼、響應內容很重要

並且,接入也很簡單,一行代碼就可以完成。

下面是嶽鷹的前端監控功能截圖,有興趣可以看看。


Step02,發現線上性能問題

接入【嶽鷹】之後,可以隨時查看項目的線上訪問性能,JS錯誤之類也會實時報警,真的是心中有數啊;心裡只有一個字,【穩】。

但是項目上線一週之後,開始收到客服反饋的問題,有不少用戶反饋頁面打開頁面比較慢、裂圖(由於我這個項目是海外的活動運營業務,頁面內容包含一些運營和動畫圖片,看不了圖片是很致命的體驗問題)。

收到問題反饋之後,第一時間就想要看看線上的實際情況,看能否找到問題根因。而從嶽鷹平臺展示的實際頁面性能,頁面的加載速度其實並不差,頁面加載耗時均值在1S左右(做過海外應用的同學應該知道這個性能不差了)。

研究了【嶽鷹】頁面性能指標的採集算法,發現頁面性能的統計是 loadEventStart - fetchStart ,對於我使用React的這個項目,頁面主流程基本都是在 load 之前之後,因此並不能很好的反映真實性能情況。

自己動手豐衣足食,這時候就需要自己來做頁面加載流程的耗時統計了。那嶽鷹支持用戶自己上報埋點嗎?一看還真支持。

Step03,自定義監控解決問題

【自定義監控】按照自定義監控協議上報即可實現一個新的監控指標,可用於業務錯誤、業務關鍵節點等監控場景。

這是自定義監控的官方介紹,剛好滿足我的監控需求。簡單看下嶽鷹自定義監控能力,支持以下幾大類。

  • "次數"型監控

如:xx包下載失敗次數、xxsdk初始化次數、xx按鈕點擊次數、xx簽到異常次數...

  • "平均值"型的監控

如:xx文件加載耗時、xx業務頁面初始化耗時、xx小程序啟動耗時、xx組件包大小...

  • "率"型的監控

如:包下載成功失敗率、緩存命中率、頁面喚起客戶端成率...

  • 分組歸類

如:監控多個包時,按包統計數據、小程序啟動耗時、按小程序id統計數據...

  • 自定義區間分佈

如:啟動耗時在1-2s、2-5s的分佈...

  • 業務自定義字段

上報一些用於輔助業務分析的字段,如:requestId、fileName...

支持上報,還要平臺支持統計分析才行。和其他監控功能(如:JS異常、頁面性能)一樣,自定義監控也提供了趨勢分析、維度分析、高級查詢、報警等功能(內心一陣竊喜)。

監控項設計

這裡結合我們的頁面流程講一下,對於用戶訪問頁面有哪些關鍵的事件。

頁面加載的第一步,會有一個過渡的 loading svg 動畫,核心是首屏的3個模塊,完成渲染即一個完整週期;也就是說,只有保證首屏3個模塊成功加載,才能讓用戶體驗到完整、流暢的頁面。

頁面流程示意如下。

基於這個頁面流程,我設計了數據加載成功率、加載耗時這2個指標。利用嶽鷹的自定義監控,我可以創建一個叫做「體感加載時長」的監控項,通過JS探針把這2個指標數據上報到平臺去。

在確定數據採集時機之後,使用如下代碼上報一條自定義數據。嗯,又是一行代碼搞定,妥妥的。

  category: 100,
  msg: '體感加載時長',
  w_succ: 1,// 初始化數據成功,不成功是為0
  wl_avg1: 94 // end - start (ms)
})

監控效果

每次版本迭代後,都可以在平臺觀察實時數據與彙總情況,實時瞭解用戶對當前頁面的直觀等待感受及作為頁面優化依據。對比上線第一版的頁面性能數據,我通過自定義監控項把用戶的真實訪問耗時統計出來了,發現用戶體感耗時3S+(我滴神。。)。

基於線上真實數據,才得以進一步優化把用戶體感耗時降到1S左右。具體做的事情包括把一些不屬於主流程的module放到首屏之後加載、大圖片優化、JS裁剪等等(具體內容這裡不展開了,有興趣以後再發文介紹)。

  • 體感耗時趨勢
  • 數據成功率趨勢

除了上述監控指標,我們還利用自定義打點來記錄script with module、vw css unit、intersectionObserver等特性的支持度(app是使用系統webview),以及一些其他的業務打點。

例如,在監控一段時間後發現 IntersectionObserver 實際支持程度達到 96%,根據這個線上結論,終於可以放心的把 100k 的 polyfill 重整為降級的替代方案。
類似的case還有很多,這裡就不贅述了。總之,監控whatever you want!

總結:怎麼為你的業務量身打造線上監控

在這個項目摸索的過程中,沉澱了一些經驗,跟大家分享下我設計自定義監控的心得,大致有以下幾種場景,以及結合嶽鷹的使用技巧。

場景1:純次數監控

如:監控某個(些)sdk初始化錯誤次數
如圖5所示,創建監控項時,只需要填寫監控項名稱、得到監控項代碼就可以了進行如下所示的打點監控了

wpk.report({
  category: 103, //平臺創建時,生成的code
  msg: 'sdk1'
})
 如果同時想監控多個sdk初始化項目,那麼也無需創建多個監控項,直接把sdk的名稱作為msg的值進行上報即可滿足你的需求

場景2:次數 + 耗時監控

如:某個重要的頁面訪問次數和從路由從創建到繪製完成耗時情況監控。
如圖5所示,相比場景1,需要 打開計算均值的開關 ,並給它取個別名叫頁面繪製耗時,打點代碼則如下所示。

wpk.report({
  category: 103, //平臺創建時,生成的code
  msg: '領取紅包頁',
  wl_avg1: 43// 頁面繪製耗時;如vue中mounted的時間減去beforeCreate的時間得到耗時
})
使用wl_avg1上報頁面繪製耗時

場景3:次數 + 耗時 + 成功率監控

如:領取紅包的次數、領取成功率、領取紅包耗時的監控。

如圖5所示,比起場景2,創建監控項時,需要 打開計算(成功)率的開關,併為其起個別名比如就叫做領取成功率,打點代碼如下所示。

// 領取紅包成功
wpk.report({
  category: 103, //平臺創建時,生成的code
  msg: '領取5元紅包',
  wl_avg1: 43,// 領取紅包接口耗時
  w_succ: 1
})
// 領取紅包失敗
wpk.report({
  category: 103, //平臺創建時,生成的code
  msg: '領取5元紅包',
  wl_avg1: 43,// 領取紅包接口耗時
  w_succ: 0
})

如果還有 ”10元紅包“、”15元紅包“等多種分類,msg的值直接填寫紅包分類即可;如果想監控的是失敗率,把監控項中 ”領取成功率“改為”領取失敗率“,上報日誌時領取成功w_succ的值設為0,而領取失敗w_succ的值設為1即可

場景4:次數 + 耗時 + 成功率 + 自定義字段

還是以領取紅包為例,當領取失敗時,不一定是接口錯誤,可能是業務上的錯誤,比如:已經領取過、沒有資格、已被送到小黑屋等。

如圖5所示,相對於場景3,需要在c1~c5中(按需)填上相應的別名,打點代碼如下所示。

// 領取紅包成功
wpk.report({
  category: 103, //平臺創建時,生成的code
  msg: '領取5元紅包',
  wl_avg1: 43,// 領取紅包接口耗時
  w_succ: 1,
  c1: 'success'
})
// 領取紅包失敗
wpk.report({
  category: 103, //平臺創建時,生成的code
  msg: '領取5元紅包',
  wl_avg1: 43,// 領取紅包接口耗時
  w_succ: 0,
  c1: '您已經領取過'
})

在自定義字段中上報了你的業務信息後,需要時,既可以作為高級查詢的查詢條件,又可以按照自定義字段的值進行聚合(groupBy)

總結

經過一輪項目實踐,總結通常應用會有兩方面的監控訴求(技術),一方面是通用的技術指標,例如性能、JS異常等;另一方面是結合業務場景的監控項(在我的這個項目裡面,有圖片加載耗時、活動環節的監控等)。
在有了清晰的監控需求,明確監控指標之後,基本都可以通過嶽鷹快速實現,真正做到事半功倍,對線上業務的運行情況瞭然於胸。

訪問嶽鷹全景監控平臺

Leave a Reply

Your email address will not be published. Required fields are marked *