1. 程式人生 > >前端業務的監控與埋點資料的上報

前端業務的監控與埋點資料的上報

我曾經在 2018 年 12 月底的時候,發表過[Vue 單頁面中進行業務資料的上報](https://www.xiabingbao.com/post/vue/vue-boss-up.html),現在這 1 年多以來,我對此也有了更深的理解。 這裡,我們還是主要探討業務資料的上報,關於頁面效能和錯誤日誌的收集上報,不在此討論範圍內。 我們前端團隊的業務資料上報功能,主要集中在新聞客戶端內部,依賴於新聞客戶端提供的特性,因此其他團隊的前端上報元件是沒辦法適應我們的需求的,這裡我本人基於之前上報的經驗,開發了一套完整的前端業務埋點資料上報元件。 在開發這套元件之前,我們要先明確幾個問題: 1. 哪些資料是可以自行收集的,哪些資料需要開發者埋點上報; 2. 開發者進行資料埋點的方式有哪些? 3. 如何保障裝置的唯一性; 4. 跳轉前的上報丟失如何處理; 5. 在新聞客戶端、微信、QQ 等環境都可以進行上報; 6. 單頁面應用中,切換頁面時如何上報; 7. 使用者並未退出頁面,而是切換了 APP,又重新切換回來怎麼辦? 8. 是否支援自定義上報的方式? 上面的這些疑問,我們一一進行了解決。 ### 1. 可以自行收集的資訊與裝置唯一性 很多資訊都是可以自行收集,而不用每個開發者都收集一遍,例如基於新聞客戶端提供的能力,可以拿到裝置資訊,已登入使用者的個人資訊,ua 等,都是可以自行收集的,然後儲存起來。 不過在新聞客戶端外,就無法拿到裝置資訊了。我在這裡,通過前端生成一個儘量唯一 的碼來標識裝置,並存儲到 cookie 和 localStorage 中,若存在則使用,若不存在則生成一個新的。以此來保證裝置的唯一性。 ```javascript let uid = cookie.getCookie('wzpuser') || localStorage.getItem('wzpuser'); if (!uid) { uid = 'gh' + Date.now() + (Math.random() + '').substr(-6); cookie.setCookie('wzpuser', uid, 360); localStorage.setItem('wzpuser', uid); } this.__data.uid = uid; return Promise.resolve(this.__data); ``` 開發者可以更加關注在頁面和使用者行為上。 ### 2. 開發者進行資料埋點的方式有哪些? 主要有 2 種方式,一個是開發者的主動上報: ```javascript reporter.send({ pagename: 'mainpage', event_id: 'banner_click', }); ``` 還有一種方式,是在 html 元素上新增`data-reporter`屬性,然後進行事件冒泡,若遇到 data-reporter 後,則進行上報;若一直冒泡到 document 上都沒有該屬性,則不上報。 ```javascript // 渲染每一個專場 const renderItem = (item: SpecialItem) => ( handleAnswer(item.ename, item.zhname, item)} > ); ``` ### 3. 跳轉前的上報丟失如何處理 我們經常需要上報點選某個連結的 pv,但通常會存在上報還沒有完成,頁面已經解除安裝了,導致上報失敗。 針對這種情況,我是在跳轉前,先儲存到本地,等下次重新回到這個頁面時,將儲存的資料進行上報。為了方便傳入和儲存,我對欄位也進行了過濾,沒有資料的欄位全部去掉,只上報有資料的欄位。 ```javascript reporter.send( { pagename: 'mainpage', event_id: 'link_click', }, 'save' ); // 先進行儲存 window.location.href = 'https://www.xiabingbao.com'; ``` ### 4. 在新聞客戶端、微信、QQ 等環境都可以進行上報 新聞客戶端中提供了一些獲取裝置資訊和使用者資訊的能力,而微信、QQ、瀏覽器等環境,只能使用前端的一些騷操作了,例如分析 cookie 中的欄位,ua 中的一些欄位等等。 這裡我也編寫了一個工具方法[https://github.com/wenzi0github/utils](https://github.com/wenzi0github/utils),將這些能力獨立出來。歡迎 star。 ### 5. 單頁面應用中,切換頁面時如何上報 這個問題沒有很好地解決,雖然能監聽到 history 路由和 hash 路由的變化([前端中的 hash 和 history 路由](https://www.xiabingbao.com/post/fe/hash-history-router.html)),但頁面的名稱需要提前定義好,而元件是不知道的,因此這裡交給開發者開進行監聽路由的變化並上報資料。 ```javascript // 每個hash路由的PV上報 router.afterEach((to) => { // to為當前已開啟的頁面,to.name為在router/index.ts中設定的name reporter.send({ pagename: to.name, event_id: 'pv', }); }); ``` ### 6. 使用者並未退出頁面,而是切換了 APP,又重新切換回來怎麼辦? 使用者沒有退出頁面,而是使用了系統級的 home 鍵,進行了 APP 的切換,其實使用者也是真實的離開了,若使用者重新回來,其實 page view 應該是要+1 的,然而頁面沒有重新整理,會產生丟失 PV 的情況。 這裡我們可以監聽頁面的可見性,當頁面重新可見時,我們就把 pv+1。當然還有一種情況要考慮到:使用者可能只是在多個 APP 中切換,當前頁面只是其中的過客而已,而使用者並沒有真的進入到這個頁面中。因此我們需要設定下重新上報 PV 的條件: - 距離上次可見時有 30 分鐘左右; - 當前可見已有 5 秒以上; ```javascript let lastShowTime = 0; // 上次可見時的時間 const visibility = new PageVisibility(); visibility.visibilityChange((isShow) => { let timer; if (isShow && Date.now() - lastShowTime >= 1000 * 60 * 30) { // 頁面可見時 timer = setTimeout(() => { report.send({ pagename: 'mainpage', event_id: 'pv', }); }, 5000); // 5秒後上報 } else { clearTimeout(timer); } }); ``` ### 7. 是否支援自定義上報的方式 元件中提供了 img 標籤上報和 post 方式的方式,如果這兩種方式也不滿足上報要求,可以自定義上報方式,並上報到對應的伺服器上。 ```javascript const report = new Report({ actid: 56, adapter: (data) => { // 要上報的資料 console.log(data); }, }); ``` ### 8. 總結 ![埋點資料上報](https://img2020.cnblogs.com/blog/443443/202009/443443-20200904123930939-1372739719.png) 通過這次業務埋點資料的上報,也瞭解了很多基礎功能的實現,同時還有如何提供自定義的能力。 歡迎我的公眾號,多多交流: ![蚊子的部落格](https://images.cnblogs.com/cnblogs_com/xumengxuan/433575/o_QQ20191010-145147