Skip to content

关于数据埋点这件事

埋点顾名思义就是在用户使用产品的过程中,记录用户的行为,以便进行产品分析和优化。记得马云演讲的时候说过一句话,一切业务数据化,一切数据业务化。

alt text

从我开始工作,就接触了埋点,有着以下几种形式

  • 入门阶段,通过接口进行埋点,记录用户的行为;这种比较适合于简单的产品,比如用户点了支付,用户是否点了对应的取消按钮
  • 进阶阶段,通过日志进行埋点,记录用户的行为;这种比较适合to c的产品,会用一套成熟的埋点系统,比如神策、诸葛IO,比较适合一些精细化的埋点

埋点分类

手动埋点(代码埋点)

手动埋点,也称为代码埋点,是指在需要统计的业务逻辑位置,通过编写代码调用埋点SDK接口来上报数据。常见的第三方统计工具如友盟、百度统计等,多采用此种方式。该方案允许开发者自定义事件和属性,适合对数据分析有精细化、深度下钻需求的场景。

全埋点(无埋点)

全埋点是指在前端自动采集用户的所有行为事件并上报,再由后端进行数据过滤与统计。这种方案的优点是前端只需集成一次埋点脚本,减少了对前后端的频繁修改,但会对服务器存储和数据处理带来一定压力。

可视化埋点

可视化埋点通过可视化界面进行操作,使埋点设置与业务代码分离。使用者可以在提供的可视化工具中选择页面元素、定义事件,系统会自动将埋点代码注入到业务代码中。这种方式降低了埋点的技术门槛,但通常仅支持预定义的控件类型,无法满足完全定制化的埋点需求。 具体可以看这篇文章,可视化埋点详解

埋点的技术实现方案

通过gif图片

这也是当下众多主流的技术实现方案。

  • 如何工作 大多都采用 1*1 的像素的透明gif来上报,因为gif的资源体积更小,不需要上报的事件名,校验 token放在 url上,已 Query String的形式拼接在图片src属性后面。
js
const img = new Image();
const data = base64.encode("event=click&text=123");
img.src = `https://example.com/track.gif?token=${token}&data=${data}`;

以下已神策为例 https://sa.datasink.sensorsdata.cn/sa.gif?project=production&token=2b881680023a0e5b&data=eyJpZGVudGl0aWVzIjp7IiRpZGVudGl0eV9jb29raWVfaWQiOiIxOWI4ZTA2MGM5NzY1OC0wZmU1YTk5Y2Y4YTAyMTgtMWM1MjU2MzEtMzY4NjQwMC0xOWI4ZTA2MGM5ODJmMjciLCIkaWRlbnRpdHlfYW5vbnltb3VzX2lkIjoic2Vuc29ycy1mYW1pbHk6MzAwMDg0In0sImRpc3RpbmN0X2lkIjoic2Vuc29ycy1mYW1pbHk6MzAwMDg0IiwibGliIjp7IiRsaWIiOiJqcyIsIiRsaWJfbWV0aG9kIjoiY29kZSIsIiRsaWJfdmVyc2lvbiI6IjEuMjYuMTMifSwicHJvcGVydGllcyI6eyJjdXN0b21lcl9pZCI6MzAwMDg0LCJzZW5zb3JzX2N1c3RvbWVyX2lkIjoic2Vuc29ycy1mYW1pbHkiLCJyb2xlIjoi5YiG5p6Q5biIIiwidXNlcl9yb2xlIjoiYW5hbHlzdCIsInVzZXJfam9iX3Bvc2l0aW9uIjoiIiwidXNlcl9uYW1lIjoiMTg4Mzg5NTk1NTkiLCJ1c2VyX2NuYW1lIjoiMTg4KioqKjk1NTkiLCJwcm9qZWN0X25hbWUiOiJFYml6RGVtbyIsInByb2plY3RfY25hbWUiOiLnlLXllYYiLCJwcm9qZWN0X2lkIjo5LCJsYXN0X2xvZ2luX3RpbWUiOiIyMDI2LTAxLTA4IDEyOjIyOjE0In0sImFub255bW91c19pZCI6InNlbnNvcnMtZmFtaWx5OjMwMDA4NCIsInR5cGUiOiJwcm9maWxlX3NldCIsInRpbWUiOjE3Njc4NDYxMzQ0NjUsIl90cmFja19pZCI6NTA5NzU0NDY2LCJfZmx1c2hfdGltZSI6MTc2Nzg0NjEzNDQ2Nn0%3D&ext=crc%3D-1088051069 data数据如下经过 base64解码如下

json
{
  "identities": {
    "$identity_cookie_id": "19b8e060c97658-0fe5a99cf8a0218-1c525631-3686400-19b8e060c982f27",
    "$identity_anonymous_id": "sensors-family:300084"
  },
  "distinct_id": "sensors-family:300084",
  "lib": { "$lib": "js", "$lib_method": "code", "$lib_version": "1.26.13" },
  "properties": {
    "customer_id": 300084,
    "sensors_customer_id": "sensors-family",
    "role": "分析师",
    "user_role": "analyst",
    "user_job_position": "",
    "user_name": "18838959559",
    "user_cname": "188****9559",
    "project_name": "EbizDemo",
    "project_cname": "电商",
    "project_id": 9,
    "last_login_time": "2026-01-08 12:22:14"
  },
  "anonymous_id": "sensors-family:300084",
  "type": "profile_set",
  "time": 1767846134465,
  "_track_id": 509754466,
  "_flush_time": 1767846134466
}

alt text 通常结合navigator.sendBeacon方法使用

优势

alt text

  • 具有天然跨域优势,如第四版《javascript高级程序设计》中描写到。
  • 无阻塞,图片是异步的,不会阻塞页面的加载和渲染。即使鞋面卸载
  • 简单可靠,所有能运行js的浏览器都支持

    劣势

  • 数据量有限:URL有长度限制(通常 2kb-8kb,因浏览器而异),无法发送大数据
  • 单项数据:无法确认数据是否发送成功
  • 仅能发送GET请求:由于图片请求是GET请求,所有的信息都保留在前端

通过接口API进行调用

示例

js
// 示例:使用 fetch API 发送
fetch("https://analytics.example.com/api/v1/track", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    event: "page_view",
    properties: { url: window.location.href, title: document.title },
  }),
  // keepalive: true  // 类似于sendBeacon,确保在页面卸载时也能发送
});
  • 优势
    • 数据量无限:POST请求没有URL长度限制,可发送任意大小数据
    • 双向数据:可以确认数据是否发送成功
    • 支持POST请求:可以发送任意数据,包括JSON、表单数据等
  • 劣势
    • 跨域问题:POST请求受同源策略限制,跨域时需要配置CORS
    • 页面卸载问题:POST请求在页面卸载时可能会被浏览器阻塞,导致数据丢失

为什么通过gif进行发送埋点?

相比PNG/JPG,GIF的体积最小最小的BMP文件需要74个字节,PNG需要67个字节,而合法的GIF,只需要43个字节。 同样的响应,GIF可以比BMP节约41%的流量,比PNG节约35%的流量。 并且大多采用的是1*1像素的透明GIF来上报 1x1像素是最小的合法图片。而且,因为是通过图片打点,所以图片最好是透明的,即使插入到dom中这样

  • 一来不会影响页面本身展示效果
  • 二者表示图片透明只要使用一个二进制位标记图片是透明色即可,不用存储色彩空间数据,可以节约体积。

如神策这样的埋点方案,就采用了1x1(GIF89a)像素的透明GIF来上报事件。

alt text

为什么要返回透明的GIF?

或许有人问直接返回 204 no content 不就行了么?为啥还要返回一个gif图片数据呢?比如HTTP CODE 返回 204 或者空响应体

http
  HTTP/1.1 204 No Content
  Access-Control-Allow-Origin: *
  Content-Length: 0
  Connection: keep-alive
  <!-- ------空响应体------ -->
  HTTP/1.1 200 OK
  Content-Type: image/gif
  Content-Length: 0
  • 兼容性 一些老的浏览器会将空响应视为错误,触发错误事件(未验证 😣 )
  • 监控方便 返回真正的图片可以让浏览器正常触发 onload/onerror 事件,方便前端监控上报状态

alt text

常用的埋点工具有哪些?

  • 神策-国内常用的埋点方案,功能完善,支持自定义事件、用户属性等。
  • 百度统计 -不够强大,不支持自定义事件、用户属性等。
  • 谷歌分析 - 出海业务用的比较多
  • 友盟 - app用的比较多
  • TalkingData - 国内常用的埋点方案,功能完善,支持自定义事件、用户属性等。
  • 阿里云 ARMS - 阿里云提供的应用性能监控服务,提供了性能埋点、错误监控、资源优化等功能。

总结

对于自由系统,如果要搭建,其实使用navigator.sendBeacon + fetch方法就行了,毕竟google现在的事项方案就是navigator.sendBeacon + fetch的方法

参考文档

can i use sendbeacon
gif 89a 规格

上次更新于: