Open l1uqi opened 1 year ago
title: 前端业务埋点SDK实践 date: 2022-11-07 categories:
参考资料:
腾讯二面:现在要你实现一个埋点监控 SDK,你会怎么设计? 为什么通常在发送数据埋点请求的时候使用的是 1x1 像素的透明 gif 图片?
最近项目需要采集用户的行为数据, 从而进行分析得到页面点击量、访问量、访问路径等重要数据, 为运营和业务人员提供精准数据,为产品优化和精细化运营提供数据支持。
这里采用代码侵入式埋点的方式进行、 SDK 提供 点击事件、曝光事件、页面时长进行上报
如何让前端同事更轻松的捕获数据、这里实现了 dom 自定义事件实现自动上报, 在 vue 中也提供了指令 如有特殊业务场景也可以使用手动进行上报。
// 自动上报 // 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] });
页面时长统计, 我们可以用时间戳来算出用户停留的页面时长。 页面离开 - 页面进入 = 停留时长。
// 单页应用 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 能够解决这个问题
document.addEventListener("visibilitychange", () => { const state = document.visibilityState; let callbackData: any = null; if (state === "hidden") { // 页面不可见 } if (state === "visible") { // 页面可见 } // 如果业务需要 时间超过1小时 则算是新开页面 自行判断 });
... 未完待续
我们采集了埋点数据后, 就需要把采集的数据交给后端。 那么我们应该如何上报? 我们得考虑接口跨域、上报异常(正在进行上报时, 用户关闭了页面, 这样上报就会失败)、性能要求(不能应用应用使用)
基于以上要求, 提供了三种方式供用户自行选择
sendBeacon 浏览器引入的 sendBeacon 方法,发出的是异步请求,但是请求是作为浏览器任务执行的, 与当前页面是脱钩的。因此该方法不会阻塞页面卸载流程和延迟后面页面的加载,用户体验较好。 缺点: 浏览器存在支持问题
img
避免跨域 1x1 像素 img 对网页内容的影响几乎没有影响 图片请求不占用 Ajax 请求限额 不会阻塞页面加载,影响用户的体验 相比 XMLHttpRequest 对象发送 GET 请求,性能上更好 触发 GET 请求之后不需要获取和处理数据、服务器也不需要发送数据
post 超出 get 最大请求数、或者用户手动进行上报方式配置则会采用 post
默认情况下优先级 sendBeacon > img > post
// 判断上传长度 2000 个字符 const urlIsLong = (url: string) => { let totalLength = 0, charCode = 0; for (var i = 0; i < url.length; i++) { charCode = url.charCodeAt(i); if (charCode < 0x007f) { totalLength++; } else if (0x0080 <= charCode && charCode <= 0x07ff) { totalLength += 2; } else if (0x0800 <= charCode && charCode <= 0xffff) { totalLength += 3; } } return totalLength < 2000 ? false : true; }; if (navigator.sendBeacon) { sendBeacon(url, params); } else if (method === "POST" || urlIsLong(str)) { xmlRequest(url, params); } else { const img = new Image(); img.src = `${url}?${str}`; }
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); } });
未完待续...
项目完整代码Github SDK使用 npm
title: 前端业务埋点SDK实践 date: 2022-11-07 categories:
埋点采集
参考资料:
腾讯二面:现在要你实现一个埋点监控 SDK,你会怎么设计? 为什么通常在发送数据埋点请求的时候使用的是 1x1 像素的透明 gif 图片?
埋点方式选择
这里采用代码侵入式埋点的方式进行、 SDK 提供 点击事件、曝光事件、页面时长进行上报
埋点方式实现
点击事件
如何让前端同事更轻松的捕获数据、这里实现了 dom 自定义事件实现自动上报, 在 vue 中也提供了指令 如有特殊业务场景也可以使用手动进行上报。
页面时长
页面时长统计, 我们可以用时间戳来算出用户停留的页面时长。 页面离开 - 页面进入 = 停留时长。
曝光
... 未完待续
埋点上报
我们采集了埋点数据后, 就需要把采集的数据交给后端。 那么我们应该如何上报? 我们得考虑接口跨域、上报异常(正在进行上报时, 用户关闭了页面, 这样上报就会失败)、性能要求(不能应用应用使用)
基于以上要求, 提供了三种方式供用户自行选择
sendBeacon 浏览器引入的 sendBeacon 方法,发出的是异步请求,但是请求是作为浏览器任务执行的, 与当前页面是脱钩的。因此该方法不会阻塞页面卸载流程和延迟后面页面的加载,用户体验较好。 缺点: 浏览器存在支持问题
img
避免跨域 1x1 像素 img 对网页内容的影响几乎没有影响 图片请求不占用 Ajax 请求限额 不会阻塞页面加载,影响用户的体验 相比 XMLHttpRequest 对象发送 GET 请求,性能上更好 触发 GET 请求之后不需要获取和处理数据、服务器也不需要发送数据
post 超出 get 最大请求数、或者用户手动进行上报方式配置则会采用 post
默认情况下优先级 sendBeacon > img > post
初始化
参数
方法
未完待续...
项目完整代码Github SDK使用 npm