Leo

关于前端数据埋点的方案

字数统计: 1.1k阅读时长: 3 min
2019/07/24 Share

一般公司都希望在项目上线后跟踪数据情况。包括新增用户、活跃用户、渠道信息、错误信息等,还有例如商城类的app,需要跟踪用户最喜欢浏览哪种类型的店铺或商品。

埋点能得到什么?

数据监控(用户行为)

  • pv,uv
  • 记录操作系统
  • 用户在每一个页面的停留时间(离开页面,进入页面)
  • 用户进入的入口
  • 用户在相应页面的触发行为,点击按钮

性能监控 (js中的performance)

  • 用户的首屏加载
  • http请求响应时间
  • 页面渲染时间
  • 页面交互动画完成时间
    关键代码

方案种类

目前各家公司从不同角度,提出了多种准确性、及时性、开发效率等问题的技术方案

  1. 代码埋点,即在需要埋点的节点调用接口直接上传埋点数据,友盟、百度统计等第三方数据统计服务商大都采用这种方案

  2. 可视化埋点,即通过可视化工具配置采集节点,在前端自动解析配置并上报埋点数据,从而实现所谓的“无痕埋点”, 代表方案是已经开源的[Mixpanel]: https://github.com/mixpanel

  3. “无埋点”,它并不是真正的不需要埋点,而是前端自动采集全部事件并上报埋点数据,在后端数据计算时过滤出有用数据,代表方案是国内的GrowingIO

代码埋点

开发者需要手动在需要埋点的节点处(例如:点击事件的回调方法、列表元素的展示回调方法、页面的生命周期函数等等)插入这些埋点代码。

1
2
3
4
const handleSubmit = () => {
// 一些业务逻辑
buriedPoint(params)
}

钉钉的做法

1
2
3
4
5
6
7
8
dd.biz.util.ut({
key: String,//打点名
value: String/JSONObject,//打点传值
onSuccess : function() {
/**/
},
onFail : function(err) {}
})

声明式埋点

将埋点代码和具体的交互和业务逻辑解耦,开发者只用关心需要埋点的控件,并且为这些控件声明需要的埋点数据即可,从而降低埋点的成本 ,在dom元素上增添埋点信息

1
2
// key表示埋点的唯一标识;act表示埋点方式
<button data-stat="{key:'search-on-click', act: 'click'}">提交啦啦啦</button>

遍历dom树,找到[data-stat]元素的节点,绑定click事件,将[data-stat]上的信息发送给服务器

缺点:

  1. 遍历DOM树的时机问题,一个简单的例子,一个表格的行数据是通过异步加载,而表格行中的操作按钮需要埋点,那么在DOM ready的时候去遍历,显然是无法找到的
  2. 绑定埋点事件次数的问题,怎样保证埋点事件不会被重复绑定到元素上,一次操作发了N个埋点请求
    重复工作很多,还要处理冒泡。

无痕埋点

我们注意到,之所以声明式埋点还需要写死代码,主要有两个原因:

  • 需要声明埋点控件的唯一事件标识
  • 有的业务字段需要在前端埋点时携带,而这些字段是在运行时才可获知的值。

对于第一点,我们可以尝试在前后端使用一致的规则自动生成事件标识,这样后端就可以配置前端的埋点行为,从而做到自动化埋点。

对于第二点,可以尝试通过某种方式将业务数据自动与埋点数据关联,这种关联可以发生在前端,也可以发生在后端。

怎么做?

采取前后端日志关联的方式,在前端请求后端API的时机,由后端将业务数据写入日志,最后在数据清洗时将相对应的前后端日志合并。
这种方式带来的问题是后端改造成本较高,并且数据清洗的开销较大,因此并不能广泛应用。但是在一些特殊场景下,例如某些业务数据只有后端可以获知,而前端不能获知时,这种关联是必要的。