最近项目需要采集用户的行为数据, 从而进行分析得到页面点击量、访问量、访问路径等重要数据, 为运营和业务人员提供精准数据,为产品优化和精细化运营提供数据支持。

1111

埋点方式选择

这里采用代码侵入式埋点的方式进行、 SDK 提供 点击事件、曝光事件、页面时长进行上报

  • 点击事件(用户每点击一次按钮、商品、区块.. 就记录一次数据)
  • 曝光事件(专区、活动、商品…用户可见)
  • 页面时长(活动、页面 停留时间)

埋点方式实现

点击事件

如何让前端同事更轻松的捕获数据、这里实现了 dom 自定义事件实现自动上报, 在 vue 中也提供了指令 如有特殊业务场景也可以使用手动进行上报。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 自动上报
// js

// vue
<button v-track:click="{
'page_id': 1,
'event_type': 12, // 事件类型
'objs' // 业务数据
}"
/>

<button v-track:keyup="{
'page_id': 2,
'event_type': 12, // 事件类型
'objs' // 业务数据
}"
/>

// 手动上报
trakerSDK.sendTracker({
'page_id': 3,
'event_type': 12,
'object_ids': [1, 2, 3]
});

页面时长

页面时长统计, 我们可以用时间戳来算出用户停留的页面时长。
页面离开 - 页面进入 = 停留时长。

1
2
3
4
5
6
7
8
9
10
11
12
13
// 单页应用
router.beforeEach((to, from, next) => {
// 获取当前时间
const timestamp = new Date().getTime();
// 上次时间
const pretimestamp = getCache(LocalStoreEnum.PRE_TIMESTAMP);
// 存入当前时间
setCache(LocalStoreEnum.PRE_TIMESTAMP, timestamp);

// 停留时间(s)
let secound = (timestamp - pretimestamp) / 1000;
next();
});

这样的话大多数场景都能够满足, 但是还有特殊场景无法满足。
如 PC 端 浏览器 Tab 选项卡切换、 APP 切换应用等。
这时候就需要另外的方案, Page Visibility API 能够解决这个问题

1
2
3
4
5
6
7
8
9
10
11
12
document.addEventListener("visibilitychange", () => {
const state = document.visibilityState;
let callbackData: any = null;
if (state === "hidden") {
// 页面不可见
}
if (state === "visible") {
// 页面可见
}

// 如果业务需要 时间超过1小时 则算是新开页面 自行判断
});

曝光


埋点上报

埋点上报

SDK

初始化

参数

参数 必填 默认值 类型
debug false bool 开启调试模式
config object {} 你的配置文件, 会在上报时传给后端
url ‘’ string 请求地址
method img string 请求方式 GET、POST、SEND_BEACON
enableHeatMap false bool 开启坐标上传 position
enableVisibilitychange false bool 开启页面可见监听, 如开启此功能 registerVueRouterEvent 传参可能为 null

方法

方法名 说明 参数
setConfig 设置全局参数 Options
sendTracker 手动上报 {自定义}
initDirectives 初始化 vue2 指令 Vue
registerVueRouterEvent 初始化 VueRouter 监听 VueRouter, callback({to, from , secound,…}, callback)
registerErrorEvent 全局异常报错 vm: Vue 对象, errorCallback((errorMsg, pageInfo) => {}) 异常回调
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import SimpleJsTracker from "simple-js-tracker";

const simpleJsTracker = new SimpleJsTracker({
debug: true,
url: "", // 服务地址
enableHeatMap: true, // 开启热力图
enableHashTracker: true,
config: {
...
}
});

// 更新传参
simpleJsTracker.setConfig(options);

// 自定义上传
simpleJsTracker.sendTracker(params);

// 初始化自定义vue2/3指令
simpleJsTracker.initDirectives(Vue);

// 初始化 VueRouter 监听
// 页面跳转监听, 上报的参数让用户自行提供 report
simpleJsTracker.registerVueRouterEvent(router, (res, report) => {
const { to, from, secound } = res;
// 页面进入
if(to.meta.tracking) {
const fromParams = {
'event_type': 5,
...to.meta.tracking,
}

report(fromParams);
}
// 页面离开
if(from.meta.tracking) {
const fromParams = {
'event_type': 6,
...from.meta.tracking,
}
report(fromParams);
}
});
// 上报拦截
simpleJsTracker.interceptors.sendTracker.use((config) => {
// ...
return config;
}, () => {});

未完待续…

文中完整代码
github > npm

参考:

腾讯二面:现在要你实现一个埋点监控 SDK,你会怎么设计?
为什么通常在发送数据埋点请求的时候使用的是 1x1 像素的透明 gif 图片?