為什麼大廠前端監控都在用GIF做埋點?

前端南玖發表於2022-02-16

什麼是前端監控?

它指的是通過一定的手段來獲取使用者行為以及跟蹤產品在使用者端的使用情況,並以監控資料為基礎,為產品優化指明方向,為使用者提供更加精確、完善的服務。

如果這篇文章有幫助到你,❤️關注+點贊❤️鼓勵一下作者,文章公眾號首發,關注 前端南玖 第一時間獲取最新的文章~

前端監控

一般來講一個成熟的產品,運營與產品團隊需要關注使用者在產品內的行為記錄,通過使用者的行為記錄來優化產品,研發與測試團隊則需要關注產品的效能以及異常,確保產品的效能體驗以及安全迭代。

所以前端監控一般也分為三大類:

資料監控(監控使用者行為)

  • PV/UV: PV(page view):即頁面瀏覽量或點選量;UV:指訪問某個站點或點選某條新聞的不同 IP 地址的人數
  • 使用者在每一個頁面的停留時間
  • 使用者通過什麼入口來訪問該網頁
  • 使用者在相應的頁面中觸發的行為,等...

統計這些資料是有意義的,比如我們知道了使用者來源的渠道,可以促進產品的推廣,知道使用者在每一個頁面停留的時間,可以針對停留較長的頁面,增加廣告推送等等。

效能監控(監控頁面效能)

  • 不同使用者,不同機型和不同系統下的首屏載入時間
  • 白屏時間
  • http 等請求的響應時間
  • 靜態資源整體下載時間
  • 頁面渲染時間
  • 頁面互動動畫完成時間,等...

這些效能監控的結果,可以展示前端效能的好壞,根據效能監測的結果可以進一步的去優化前端效能,儘可能的提高使用者體驗。

異常監控(監控產品、系統異常)

及時的上報異常情況,可以避免線上故障的發上。雖然大部分異常可以通過 try catch 的方式捕獲,但是比如記憶體洩漏以及其他偶現的異常難以捕獲。常見的需要監控的異常包括:

  • Javascript 的異常監控
  • 樣式丟失的異常監控

埋點上報

OK,上面我們說到了前端監控的三個分類,瞭解了一個產品需要監控哪些內容以及為什麼需要監控這些內容,那麼我們應該怎麼實現前端監控呢?

實現前端監控,第一步肯定是將我們要監控的事項(資料)給收集起來,再提交給後臺進行入庫,最後再給資料分析組進行資料分析,最後處理好的資料再同步給運營或者是產品。資料收集的豐富性和準確性會直接影響到我們做前端監控的質量,因為我們會以此為基礎,為產品的未來發展指引方向。

現在常見的埋點上報方法有三種:手動埋點、視覺化埋點、無埋點

手動埋點

手動埋點,也叫程式碼埋點,即純手動寫程式碼,呼叫埋點 SDK 的函式,在需要埋點的業務邏輯功能位置呼叫介面,上報埋點資料,像[友盟][百度統計]等第三方資料統計服務商大都採用這種方案。手動埋點讓使用者可以方便地設定自定義屬性、自定義事件;所以當你需要深入下鑽,並精細化自定義分析時,比較適合使用手動埋點。

手動埋點的缺陷就是,專案工程量大,需要埋點的位置太多,而且需要產品開發運營之間相互反覆溝通,容易出現手動差錯,如果錯誤,重新埋點的成本也很高。

視覺化埋點

通過視覺化互動的手段,代替上述的程式碼埋點。將業務程式碼和埋點程式碼分離,提供一個視覺化互動的頁面,輸入為業務程式碼,通過這個視覺化系統,可以在業務程式碼中自定義的增加埋點事件等等,最後輸出的程式碼耦合了業務程式碼和埋點程式碼。

視覺化埋點的缺陷就是可以埋點的控制元件有限,不能手動定製。

無埋點

無埋點則是前端自動採集全部事件,上報埋點資料,由後端來過濾和計算出有用的資料。優點是前端只要一次載入埋點指令碼,缺點是流量和採集的資料過於龐大,伺服器效能壓力山大。

為什麼都用GIF來做埋點?

發現過程

首先說一下我是怎麼發現的,前一段時間,產品提了個需求,說我們現在的書籍曝光上報規範並不是他們想要的資料,並且以後所有頁面的書籍上報都統一成最新規範。

曝光規範:

  • 書籍出現在可視區並停留1秒,算作有效曝光
  • 書籍不能重複曝光,假如它一直在可視區滾動時只能上報一次
  • 當它移出可視區後再回到可視區,再按第一點進行曝光

OK,既然要所有頁面統一,那就只能封裝成通用庫來使用了,這裡實現邏輯就不貼了,想看的私聊我發你,主要的難點就是停留時長計算,以及曝游標記。

const exposeReportClass = new exposeReport({
      scrollDom: "",  // 滾動容器,建議指定一個滾動容器,不傳預設為window
      watchDom: ".bookitem", // 監聽的dom,建議使用class類,標籤也支援
      time: 1000             // 停留有效時長ms
});
// 提供兩個上報方法
exposeReportClass.didReport(()=>{
  // 手動上報
  //callback
})
exposeReportClass.scrollReport(()=>{
  // 滾動動上報
  //callback
})
// 

具體業務邏輯之需要放在對應的callback裡面,而上報邏輯開發者無需考慮,因為我底層已經統一處理好了。

然後我再測試的時候就發現,上報發的請求居然是通過圖片發起的,並不是我們認為的介面上報。

report.png

然後我去查了下資料,發現很多大廠的上報都是這麼幹的!

使用GIF上報的原因

向伺服器端上報資料,可以通過請求介面,請求普通檔案,或者請求圖片資源的方式進行。只要能上報資料,無論是請求GIF檔案還是請求js檔案或者是呼叫頁面介面,伺服器端其實並不關心具體的上報方式。那為什麼所有系統都統一使用了請求GIF圖片的方式上報資料呢?

  • 防止跨域

一般而言,打點域名都不是當前域名,所以所有的介面請求都會構成跨域。而跨域請求很容易出現由於配置不當被瀏覽器攔截並報錯,這是不能接受的。但圖片的src屬性並不會跨域,並且同樣可以發起請求。(排除介面上報)

  • 防止阻塞頁面載入,影響使用者體驗

通常,建立資源節點後只有將物件注入到瀏覽器DOM樹後,瀏覽器才會實際傳送資源請求。反覆操作DOM不僅會引發效能問題,而且載入js/css資源還會阻塞頁面渲染,影響使用者體驗。

但是圖片請求例外。構造圖片打點不僅不用插入DOM,只要在js中new出Image物件就能發起請求,而且還沒有阻塞問題,在沒有js的瀏覽器環境中也能通過img標籤正常打點,這是其他型別的資源請求所做不到的。(排除檔案方式)

  • 相比PNG/JPG,GIF的體積最小

最小的BMP檔案需要74個位元組,PNG需要67個位元組,而合法的GIF,只需要43個位元組。

同樣的響應,GIF可以比BMP節約41%的流量,比PNG節約35%的流量。

並且大多采用的是1*1畫素的透明GIF來上報

1x1畫素是最小的合法圖片。而且,因為是通過圖片打點,所以圖片最好是透明的,這樣一來不會影響頁面本身展示效果,二者表示圖片透明只要使用一個二進位制位標記圖片是透明色即可,不用儲存色彩空間資料,可以節約體積。

推薦閱讀

原文首發地址點這裡,歡迎大家關注公眾號 「前端南玖」

我是南玖,我們下期見!!!

相關文章