前端埋点框架(前端埋点sdk)

前端埋点框架(前端埋点sdk)作者 熊的猫 相信不少人因为项目中没有接触过数据埋点相关的内容 而没有花时间去了解它 总觉得这又是一个自己还不能涉及的方面 然而数据埋点本身并不难理解 只是很难做得好 本文会从 认识数据埋点 SDK 设计前端数据埋点 SDK 两个核心方面来展开 聊聊前端数据埋点的那些事 SDK 全称是 Software Development Kit 即 软件开发工具包 一般都是一些软件工程师为特定的软件包 软件框架 硬件平台 操作系统等建立应用软件时的开发工具的集合 对产品本身而言




作者:熊的猫

相信不少人因为项目中没有接触过数据埋点相关的内容,而没有花时间去了解它,总觉得这又是一个自己还不能涉及的方面,然而数据埋点本身并不难理解,只是很难做得好,本文会从 认识数据埋点 SDK设计前端数据埋点 SDK两个核心方面来展开,聊聊前端数据埋点的那些事。

SDK全称是 Software Development Kit
软件开发工具包,一般都是一些软件工程师为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件时的开发工具的集合。

对产品本身而言,我们需要关注内容包括如下几个方面:

  • 用户在产品里 主要做什么操作、停留多久、访问几次
  • 用户点击率占比如何,会不会出现某些功能设计对于用户而言是无效的
  • 用户在核心使用流程上是否顺畅,页面反馈是否正常友好
  • 可能有哪些潜在的用户的功能需要更新

总的来说,数据埋点 核心是为了 收集数据(有了数据就可以为所欲为),只有通过分析数据,才能更好的评估出整个项目的质量和重要性(数据为王),并且能够为产品优化指明方向(数据驱动产品)。

数据埋点的核心是数据收集,而与数据相关的内容不外乎如下几个内容:

  • 数据又是基于应用产生的,因为没有应用就不会有相关的数据
  • 应用本身要提供展示、收集、操作内容,而这是基于平台的,比如网站就是基于浏览器平台
  • 有应用、有平台就得有用户,因为应用本身就是为了给用户提供好用的功能去解决某些存在的问题
  • 针对开发者而言,应用就是代码,代码运行的质量也能决定应用的质量,而显式质量体现在错误或警告上

总结下来,数据埋点其实要考虑的就是 用户行为错误警告页面性能 三个核心方面。

用户行为就是在网页应用中进行的一系列操作,但用户的操作有很多种,都需要记录下来是不可能的,一般需要记录用户的以下几种行为:

  • 用户浏览页面次数,PV(Page View)
  • 用户每次访问网站中的一个页面就被记录为 1 个 PV,多次访问同一个页面,访问量就会累计
  • 页面浏览用户数,UV(Unique visitor)
  • 通过网络正常访问页面的使用者,通常一台电脑客户端或一个用户账号为一个访客,一般同一个客户端或用户账号在 24h 内多次访问只会被记录为 1 个 UV,计算策略视具体情况而定
  • 用户点击按钮次数
  • 以上两种可以认为是自动式触发埋点,而点击按钮次数就属于是互动式触发埋点,便于去了解这个功能按钮的使用情况

页面中代码运行产生的错误,可能会导致用户核心操作流程被中断,为了避免大量用户受到影响,我们需要获取 生产环境的错误数据,这样才能便于开发者及时进行修复。

通常来讲代码中的错误会包含以下几大类:

  • 全局错误,即未被捕获的错误
  • 局部错误,即通过 try...catch、promise.then、promise.catch
  • 接口请求错误,即在二次封装请求 API
  • 组件级错误,即使用 Vue/React 组件时发生的错误

页面性能其实也是前端性能优化中一个需要考虑和优化的点,毕竟如果一个网站老是发生 白屏、交互卡顿、页面资源加载时间长 等问题,肯定是没办法留住用户的,特别是用户的真实环境各不相同,如 Windows x、MACOS、Android、iOS 等,更加需要统计和收集相关数据,便于进行集中优化处理,提升用户体验。
与页面性能指标相关的内容,在之前的 前端性能优化到底该怎么做(上)— 开门见山一文中有提到,这里大致总结下:

  • 首次绘制(First Paint,FP)
  • 在渲染进程确认要渲染当前响应资源后,渲染进程会先创建一个空白页面,通常把创建空白页面的这个时间点称为 First Paint,简称 FP
  • 所谓的 白屏时间 其实指的就是创建这个空白页面到浏览器开始渲染非空白内容的时间,比如页面背景发生变化等
  • 首次内容绘制(First Contentful Paint,FCP)
  • 当用户看见一些 "内容" 元素被绘制在页面上的时间点,和白屏是不一样,它可以是 文本 首次绘制,或 SVG 首次出现,或 Canvas 首次绘制等,即当页面中绘制了第一个 像素 时,这个时间点称为 First Content Paint,简称 FCP
  • 首屏时间 / 最大内容绘制(Largest Contentful Paint, LCP)
  • LCP 是一种新的性能度量标准,LCP 侧重于用户体验的性能度量标准,与现有度量标准相比,更容易理解与推理,当首屏内容完全绘制完成时,这个时间点称为 Largest Content Paint,简称 LCP
  • 最大内容绘制应在 2.5s
  • 首次输入延迟(First Input Delay, FID)
  • FID 测量的是当用户第一次在页面上交互的时候(点击链接、点击按钮 js),到浏览器实际开始处理这个事件的时间
  • 首次输入延迟应在 100ms 内完成
  • 累积布局偏移(Cumulative Layout Shift, CLS)
  • CLS 是为了测量 视觉稳定性,以便提供良好的用户体验
  • 累积布局偏移应保持在 0.1
  • 首字节达到时间(Time to First Byte,TTFB)
  • 指的是浏览器开始收到服务器响应数据的时间(后台处理时间 + 重定向时间),是反映服务端响应速度的重要指标
  • TTFB 时间如果超过 500ms,用户在打开网页的时就会感觉到明显的等待

理解了 为什么要做前端数据埋点 和 前端数据埋点所需要统计数据的方方面面,接下来我们就需要设计一个自己的 前端数据埋点 SDK 了。

这里只我们考虑数据埋点的核心内容,因此不会涉及得肯定没有那么全面,而一开始也不可能设计得全面,只要保证核心功能,那么在基于核心进行扩展即可。

应用的唯一标识 — options.AppId

数据埋点 SDK 作为一个通用的工具集,是可供多个系统进行使用的,而这就意味着需要去保证每个应用的唯一性,一般来讲,在初始化 SDK 的时候是需要接入方提供的当前应用的 ID

那这个 ID 从何而来?随便生成吗?一般来说需要经过如下步骤:

  • 在对应监控系统上为当前应用生成唯一的 AppId
  • 在对应应用接入 SDK 时作为配置项之一传入

其实还会涉及到请求 url 内容,主要用于发送给对应的监控系统,因此 options 核心内容简单设计如下:

数据发送格式 — data

由于需要收集的数据类型包含多种,最好能够定义一种比较通用的数据格式,便于更友好地进行数据收集。

这里简单定义一下数据格式,大致如下,格式随需求场景产生差异:

确定数据发送方式

如果要问前端埋点最基本要实现的功能是什么,那必然是 数据发送 的能力,否则即便有应用、有用户、有数据也只能保存在本地没法发送给相应的监控系统,意味就没法进行收集和统计(数据等于白给)。

那么数据发送都有什么方式呢?针对这个问题把 数据发送 翻译成 请求发送 就容易多了,转而问题就变成了 请求发送方式都有哪些?

一般会包括如下几种(包括但不限于):

  • XMLHttpRequest
  • fetch
  • form 表单的 action
  • 基于元素 src 属性的请求
  • img 标签的 src
  • script 标签的 src
  • Navigator.sendBeacon()

这里选择的是最后一种,因为 Navigator.sendBeacon() 就是专门用于通过 HTTP POST[1] 将统计数据 异步[2] 发送到 Web

传统技术发送统计数据的一些问题,可以直接通过 传送门[3] 查看,由于文章篇幅有限不在额外解释。

这里我们只考虑极简情况,设计好的 SDK 代码内容比较简单,直接上代码:

统计 PV 和 UV — 自动触发埋点

关于 PVUV 在上述已经做过介绍了,本质上这两个数据统计都可在一个上报类型为 action 数据发送中获得,主要看监控系统是按照怎样的规则对数据进行分析和统计,这里在 SDK 内部监听了页面的 pageshow / pagehide

  • 在pageshow中可以上报与PV / UV相关的数据 和 页面性能相关的数据
  • 在 pagehide 中主要用于计算用户停留在页面上的时间 timeOnPage

统计用户点击按钮 — 交互式触发埋点

假设我们希望记录某些按钮的使用次数的数据,可以在 document 上监听 click 事件,目的利用事件冒泡以便于不需要侵入不同按钮的 click

和页面性能相关的内容,属于 SDK 自动触发埋点,不应该让使用者在手动接入,在上面的实现中,我们在 pageshow 事件中通 reportWebVitals 和 performanceReport 进行数据上报,并且这里选择了 Google 推出的 web-vitals[4] 来获取和页面性能指标相关的具体数据,对应代码为:

获取得到的数据大致如下:

数据埋点SDK架构 数据埋点工具_javascript

全局错误

全局错误,即未被捕获的错误,可以通过 window.onerror 事件来捕获,然后进行错误数据上报,大致如下:

局部错误

局部错误,即通过 try...catch、promise.then、promise.catch 等捕获的错误,大致使用如下:

接口请求错误接口请求错误,即在二次封装请求 API 中进行请求和接收响应时的错误,为了方便这里以 axios 来举例子,我们可以在它的 请求拦截响应拦截 的第二个回调参数中去上报对应的错误数据信息,大致如下:

组件级错误

组件级错误,即使用 Vue / React

  • Vue中的 errorHandler
  • React中的 ErrorBoundary 错误边界相关的 getDerivedStateFromError 和 componentDidCatch钩子

现在我们了解了 前端数据埋点 SDK 的二三事,通过上面的例子可能让你觉得看起来比较简单,但是真的要做好数据埋点也必然没有那么容易,比如好需要考虑你的 SDK 数据发送的时间、发送的次数、需不需要将某些数据信息整合在一起只发送一次、怎么避免网络拥塞等等问题。
参考资料

[1]
HTTP POST: https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/POST
[2]
异步: https://developer.mozilla.org/zh-CN/docs/Glossary/Asynchronous
[3]
传送门:https://developer.mozilla.org/zh-CN/docs/Web/API/Navigator/sendBeacon
[4]
web-vitals:https://www.npmjs.com/package/web-vitals

编程小号
上一篇 2025-02-23 08:46
下一篇 2025-02-27 08:33

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ri-ji/34563.html