> For the complete documentation index, see [llms.txt](https://tech.banchengyun.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://tech.banchengyun.com/archives/frontend/tracking.md).

# 前端埋点

## 前端埋点

> 前言：太良日常的工作，很大一部分是跟进线上用户的问题，所以以下类型的对话就成了频率非常高的存在。

![img](https://scrm0.cdn.banchengyun.com/material/9c053d93669be69cb8b06b92e91a7f69890dc6f3.png)

那就引发了一个思考，我怎么在用户发生错误，或者进行某种行为的时候，收集到他的动作与一系列可分析的内容？答案就是前端的埋点。

### 埋点的目的

获取用户行为以及跟踪产品在用户端的使用情况，并以监控数据为基础，指明产品优化的方向。

前端监控可以分为三类：数据监控、性能监控和异常监控。

### (1) 数据监控

数据监控，顾名思义就是监听用户的行为。常见的数据监控包括：

* PV/UV:PV(page view)，即页面浏览量或点击量。UV:指访问某个站点或点击某条新闻的不同IP地址的人数
* 用户在每一个页面的停留时间
* 用户通过什么入口来访问该网页
* 用户在相应的页面中触发的行为

**统计这些数据是有意义的，比如我们知道了用户来源的渠道，可以促进产品的推广，知道用户在每一个页面停留的时间，可以针对停留较长的页面，增加广告推送等等。**

### (2) 性能监控

性能监控指的是监听前端的性能，主要包括监听网页或者说产品在用户端的体验。常见的性能监控数据包括：

* 不同用户，不同机型和不同系统下的首屏加载时间、白屏时间
* http等请求的响应时间
* 静态资源整体下载时间
* 页面渲染时间
* 页面交互动画完成时间

**这些性能监控的结果，可以展示前端性能的好坏，根据性能监测的结果可以进一步的去优化前端性能，比如兼容低版本浏览器的动画效果，加快首屏加载等等。**

### (3) 异常监控

此外，产品的前端代码在执行过程中也会发生异常，因此需要引入异常监控。及时的上报异常情况，可以避免线上故障的发上。虽然大部分异常可以通过try catch的方式捕获，但是比如内存泄漏以及其他偶现的异常难以捕获。常见的需要监控的异常包括：

* Javascript的异常监控
* 样式丢失的异常监控。

## 埋点分为什么？

![img](https://scrm0.cdn.banchengyun.com/material/d5ebdd789eccdc579c1dfacbe1d1ed3e84703f1c.png)

### 手动埋点

```html
// 手动埋点也叫做代码埋点，在每一处需要的地方，都加一段上报代码逻辑，统计用户的关键行为。

// 实现起来最快，收集到的内容可高度自定义，但影响代码的阅读体验，且散落的代码不方便管理，代码越来越像这样，谁接手谁倒霉，下面我们来看实际代码
```

![img](https://scrm0.cdn.banchengyun.com/material/e8f613de0d75e25601a17c45c8938ece900af88f.png)

### 可视化埋点

通过可视化交互的手段，代替上述的代码埋点。 将业务代码和埋点代码分离，提供一个可视化交互的页面，输入为业务代码， 通过这个可视化系统，可以在业务代码中自定义的增加埋点事件等等， 最后输出的代码耦合了业务代码和埋点代码。

缺点就是可以埋点的控件有限，不能手动定制。 可视化埋点听起来比较高大上，实际上跟代码埋点还是区别不大。 也就是用一个系统来实现手动插入代码埋点的过程。 比如国外比较早做可视化的是Mixpanel， 国内较早支持可视化埋点的有TalkingData、诸葛 IO，2017年腾讯的MTA也宣布支持可视化埋点；

相比于手动埋点更新困难，埋点成本高的问题，可视化埋点优化了移动运营中数据采集的流程， 能够支持产品运营随时调整埋点，无需再走发版流程，直接把配置结果推入到前端， 数据采集流程更简化，也更方便产品的迭代。可视化埋点中多数基于Xpath的方案， XPath 是一门在 XML 文档中查找信息的语言，XPath 可用来在 XML 文档中对元素和属性进行遍历。

### 无痕埋点

无痕埋点也叫全埋点，通过控件绑定触发事件，事件被触发的时候系统会有相应的事件让开发者处理这些行为。

### 实现埋点

#### 最简单的埋点

```js
// 通过window对象的onerror监听，获取所有报错的内容。
window.onerror = function (message, source, lineno, colno, error) {
    console.log(message);
    console.log(source);
    console.log(lineno);
    console.log(colno);
    console.log(error);
};

console.log(test);
```

#### 晋级 => 实现一个简单的无痕埋点

> 借助createElement，通过劫持的形式主动上报，具体看代码

```jsx
// js
import React from 'react'

export const initTrack = ({ onClickEvent }) => {

  const createElement = React.createElement

  const handleEditClick = props => {
    const click = props.onClick
    console.log(props)
    props.onClick = e => {
      onClickEvent && onClickEvent(props.data)
      click && click(e)
    }
  }

  React.createElement = function () {
    const args = Array.prototype.slice.call(arguments)
    console.log(args)
    let zhihong = args[1]

    if (zhihong && zhihong.data) {
      zhihong = handleEditClick(zhihong)
    }
    return createElement.apply(null, args)
  }
}
```

```jsx
// jsx
import React, { useEffect } from 'react'

import { initTrack } from './track'

const Test = () => {
  initTrack({
    onClickEvent: data => {
      // 我在这里 给后端上报咯～～～
      console.warn(data)
    }
  })

  return (
    <>
      <a data={{ test: 2 }}>222</a>
      <div
        style={{ fontSize: 40 }}
        onClick={() => {
          console.log('点击')
        }}
        data={{
          a: 1,
          b: 2
        }}
      >
        我要点击
      </div>
    </>
  )
}

export default Test
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://tech.banchengyun.com/archives/frontend/tracking.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
