Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

前端埋点方案 #77

Closed
PolluxLee opened this issue Aug 4, 2018 · 0 comments
Closed

前端埋点方案 #77

PolluxLee opened this issue Aug 4, 2018 · 0 comments
Labels

Comments

@PolluxLee
Copy link
Owner

PolluxLee commented Aug 4, 2018

# 定义

所谓埋点就是在应用中特定的流程收集一些信息,用来跟踪应用使用的状况,后续用来进一步优化产品或是提供运营的数据支撑,包括访问,访客,停留时间,页面查看和跳出率等等

# 前端埋点主要方式

1. 代码埋点

在需要埋点的节点调用接口,携带数据上传

优点: 灵活,不会产生多余的上报

缺点: 埋点成本高,每次业务需求,产品都要出一份埋点文档,开发人员需要手动添加埋点代码

2. 可视化埋点

通过可视化工具配置采集节点,在前端自动解析配置并上报埋点数据

优点: 只需产品人员配置采集节点,不需要出埋点文档,开发不需要手动埋点,定制化程度高,不会产生多余的上报

缺点: 需要有可视化配置页面并实现圈选功能,前期搭建成本较高,客户端比较适合使用,前端因浏览器请求和渲染机制的原因,不太适合

3. 无埋点

页面引入埋点文件后,自动收集并上报页面相关信息和用户的交互行为信息

优点: 产品无需提供埋点文档,不需要在后台配置,前端开发人员无需手动添加埋点代码

缺点: 全量上报,接口压力大,存在冗余上报;页面元素的唯一性有时无法确定,导致上报有误差

# 代码埋点

1. 命令式埋点

开发者需要手动在需要埋点的节点处进行埋点。如点击按钮或链接后的回调函数、页面 ready 时进行请求的发送

// 页面加载时发送埋点请求
$(document).ready(function(){
   // ... 这里存在一些业务逻辑
   sendRequest(params);
});
// 按钮点击时发送埋点请求
$('button').click(function(){
   // ... 这里存在一些业务逻辑
   sendRequest(params);
});

缺点: 埋点代码与业务代码高度耦合,使得整体业务代码变得繁琐,容易出错,难以维护

所以,我们需要让埋点的代码与具体业务逻辑解耦,提高埋点的效率和代码的可维护性

2. 声明式埋点

解耦之后,于是有了声明式埋点。在这里,需要关注两个点:

  • 需要埋点的 DOM 节点
  • 所需携带的数据
// key 表示埋点的唯一标识;act 表示埋点方式
<button data-stat="{key:'111', act: 'click'}">埋点</button>

通过遍历 DOM 树,找到属性为 [data-start] 的节点,给这个 button 绑定 click 事件,在事件处理函数中将数据通过请求上报

# 基于 Vue 指令的声明式埋点

问题

  • 遍历DOM树的时机问题,一个简单的例子,一个表格的行数据是通过异步加载,而表格行中的操作按钮需要埋点,那么在DOM ready的时候去遍历,显然是无法找到的
  • 绑定埋点事件次数的问题,怎样保证埋点事件不会被重复绑定到元素上,一次操作发了N个埋点请求?
  • 如何处理特有的埋点行为,如页面展现埋点,区域展现埋点?
  • 如何在解绑时,销毁已绑定的事件?

Vue 自定义指令钩子

  • bind: 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

  • inserted: 被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

  • update: 所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。

  • componentUpdated: 指令所在组件的 VNode 及其子 VNode 全部更新后调用。

  • unbind: 只调用一次,指令与元素解绑时调用

操作

Vue.directive('stat', {
  bind: function () {
    // 准备工作
  },
  update: function (newValue, oldValue) {
    // 值更新时的工作
    // 也会以初始值为参数调用一次, 此时可以根据传值类型来进行相应埋点行为的请求处理
  },
  unbind: function () {
    // 清理工作
  }
})

# 参考

https://juejin.im/entry/5958e9086fb9a06bb95abe4a

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant