前端埋點統計方案思考
埋點即監控使用者在應用表現層的行為,於產品迭代而言至關重要。埋點資料分析是產品需求的 來源 ,檢驗功能是否達預期的 佐證 。
採集埋點資料可做如下分析(以百度統計為例):
將 使用者屬性 、 使用者行為 轉化各類視覺化圖表:
不同產品對資料的關注角度不同,可按需採集。如資訊流產品對停留時長的關注度更高(統計頁面訪問 & 跳出時間),商城類較注重“復購率”(統計新老使用者),廣告類更追求最大限度。
埋點統計通常分兩類:
-
頁面訪問量統計
-
功能點選量統計
頁面訪問量統計
頁面訪問量統計通常分兩類:
-
PV:頁面訪問人次
-
UV:頁面訪問人數
頁面訪問量,並非僅僅取決於其內容吸引力,影響因素包含入口 外觀 、 位置 、 深度 等等(在此不考慮剛需)。入口外觀屬 UI 設計範疇,入口位置可通過分析使用者點選熱力圖調整,入口深度可通過分析使用者訪問路徑調整。
使用者點選 熱力圖 形如:
將核心頁面入口置於熱力圖紅色區域?
採集頁面載入 from 、 to 以獲知使用者訪問路徑:
分析可知使用者普遍 訪問深度 、每一深度 & 每一頁面的 流失率 等,依照結果調整核心頁面入口源、入口深度?
頁面訪問量,也並非僅僅取決於產品設計。假若 PV 穩定的頁面訪問量 爆跌 ,便需考慮其載入成功率了(或許是枚技術 bug)。
前端如何實現全域性 PV 統計,以 Vue 應用為例。
方案一
通過在入口檔案 index.js 全域性定義 Router.beforeEach :
import App from './app' import Router from './router' Router.beforeEach((to, from, next) => { App.logEvent({ type: 'visit', name: to.name, time: new Date().valueOf(), params: { from: { name: from.name, path: from.path, query: from.query }, to: { name: to.name, path: to.path, query: to.query } } }) next() })
停留時長可通過 (跳轉頁 time - 當前頁 time) 獲知,但關閉應用時如何統計?監聽應用關閉 API/Window/onbeforeunload" rel="nofollow,noindex" target="_blank">onbeforeunload + onunload ?
其中 App.logEvent 為自定義 Vue 外掛 App 中的 method,用於向伺服器發起 埋點上報請求 :
import Request from './utils/request' const App = { // ... logEvent (opts) { Request({ url: '/log/event', method: 'POST', data: { type: opts.type, name: opts.name, time: opts.time, params: opts.params || {} } }) } } App.install = (Vue, options) => { Vue.prototype.$app = { // ... logEvent: App.logEvent } } export default App
方案二
通過在入口檔案 index.js 全域性註冊混入 beforeRouteEnter 、 beforeRouteLeave 物件:
import Vue from 'vue' Vue.mixin({ beforeRouteEnter (to, from, next) { next(vm => { vm.$app.logEvent({ type: 'visit', name: to.name, time: new Date().valueOf(), params: { from: { name: from.name, path: from.path, query: from.query }, to: { name: to.name, path: to.path, query: to.query } } }) }) }, beforeRouteLeave (to, from, next) { this.$app.logEvent({ type: 'visit', name: to.name, time: new Date().valueOf(), params: { from: { name: from.name, path: from.path, query: from.query }, to: { name: to.name, path: to.path, query: to.query } } }) next() } })
關閉應用時 beforeRouteLeave 是否觸發?
上述方案存在明顯缺陷:
-
官方曰慎用全域性混入物件!!!
-
對於頁面同名鉤子函式 beforeRouteEnter 、 beforeRouteLeave ,如何 merge ?如何 next ?
-
含子路由的頁面將呼叫 2 次 beforeRouteEnter 、 beforeRouteLeave ,PV 無形翻倍…
我猜此刻有打全域性混入 created 、 destroyed 並通過 this.$route 獲知訪問物件主意的人了,試試看?
令人不知所措的輸出,列印次數與 路由表 長度一致嗷~
其中 this.$app.logEvent(vm.$app.logEvent) 等同方案一中 App.logEvent ,不再贅述。
如何恰當選取全域性 PV 統計方案?
-
SPA 應用:僅單入口,在入口檔案全域性定義 Router.beforeEach 方便可行。
-
MPA 應用:多入口,在每個入口檔案定義 Router.beforeEach ?可封裝公用邏輯(偽裝單入口),免去重複構造 entry 的成本。
-
SPA + MPA 混合應用:emmmmmm…採用 MPA 應用的統計方案。
-
SSR 應用:為追求更好的 SEO 而採用服務端渲染(SSR)。以 Jinja(Python 模板) 為例,呼叫 TemplateView 則為渲染頁面(不同於前後端分離專案,服務端無法獲知介面呼叫與頁面渲染的對應關係),統計其呼叫次數及 TemplateName 可知頁面 PV。
至於 UV,統計 PV 時採集 userId 去重即可。若應用無使用者管理體系,採集 IP 、 deviceId 也可粗略得知 UV(不精準)。
功能點選量統計
不同功能的點選量不同,同一功能不同區域的點選量也不同:
按鈕點選量,影響因素包含按鈕 外觀 、 位置 、 入口 等等(在此不考慮剛需)。按鈕外觀屬 UI 設計範疇,按鈕位置可通過分析使用者點選熱力圖調整,按鈕入口可通過分析觸發源分佈調整。
舉一例項:
運營同學會將一張圖片裁切成 n 個區域,點選每一區域所推薦商品不同。統計區域點選座標,據熱力圖調整商品排序以求 利益最大化 。
前端如何實現功能點選量統計?
本人將功能點選分兩類:
-
帶業務介面請求
-
無業務介面請求
方案一
將埋點上報混入業務介面請求,無介面請求的點選採用自定義上報:
其中 param keys 指代需上報的業務請求引數 key list (並非全部引數均需隨埋點上報)。
上述方案大大節約請求數,但存在明顯缺陷:
-
將埋點上報混入業務介面,上報 crash 不僅丟失統計資料,還將影響主功能。
-
統計與業務 高耦合 ,兩者儘量不混於同一服務。
方案二
將所有點選事件視為同一類,走統一上報介面:
logEvent (opts) { Request({ url: '/log/event', method: 'POST', data: { type: opts.type, name: opts.name, time: opts.time, params: opts.params || {} } }) }
上述方案也存在明顯缺陷:
-
請求量翻倍:但統計與業務服務拆分後,請求並非同一組伺服器承擔。
-
待上報的點選事件函式均需呼叫 logEvent :封裝一枚附帶埋點上報的 元件 ,以 Vue 為例。
<template> <div class="vc-trace" @click="triggerClick"> <slot></slot> </div> </template> <script> import Request from './utils/request' export default { name: 'Trace', props: { type: { type: String, default: '' }, name: { type: String, default: '' }, from: { type: String, default: '' }, params: { type: Object, default: () => ({}) } }, methods: { triggerClick () { Request({ url: 'XXX/log/event', method: 'POST', data: { type: this.type, name: this.name, from: this.from, time: new Date().valueOf(), params: this.params } }) } } } </script>
方案本無優劣,適合才更重要,需綜合考慮 產品設計 、 產品使用度 、 服務利用率 等等。例使用度較低應用可將統計與業務混於同一服務以節約成本,使用度較高應用可採取 本地快取 、 批量上報 以降低服務壓力,但批量上報是否加大統計 誤差 ?
本文所述僅冰山一角,歡迎大家留言寶貴經驗~
作者:呆戀小喵
我的後花園: https://sunmengyuan.github.io/garden/
我的 github: https://github.com/sunmengyuan
原文連結: https://sunmengyuan.github.io/garden/2018/12/13/trace.html