前端業務的監控與埋點資料的上報
阿新 • • 發佈:2020-09-04
我曾經在 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