前端埋点实现:用户行为统计
前端埋点实现:用户行为统计
/c8software/sensordata-demo
主要内容
- Event Listeners:监听用户交互。
- Performance API:获取页面加载时间。
- navigator.sendBeacon:可靠发送数据。
- JavaScript 原生 API:确保轻量和兼容性。
1:初始化项目
1
2
3
4
mkdir behavior-tracking
cd behavior-tracking
npm init -y
npm install rollup --save-dev
文件结构:
1
2
3
4
5
6
7
behavior-tracking/
├── src/
│ ├── index.js # 主入口
│ ├── tracker.js # 埋点逻辑
│ ├── report.js # 数据上报
├── rollup.config.js
└── package.json
2:埋点逻辑实现
在 src/tracker.js
中,实现行为统计:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
export class BehaviorTracker {
constructor() {
this.events = [];
this.startTime = Date.now();
this.init();
}
init() {
// 页面浏览
this.trackPageView();
// 点击事件
document.addEventListener('click', (e) => {
const target = e.target;
if (target.tagName.match(/^(A|BUTTON|INPUT)$/)) {
this.trackClick(target);
}
});
// 页面卸载时计算停留时间
window.addEventListener('unload', () => {
this.trackStayTime();
});
}
trackPageView() {
this.events.push({
type: 'pageview',
url: window.location.href,
title: document.title,
timestamp: Date.now(),
loadTime: performance.timing.loadEventEnd - performance.timing.navigationStart
});
}
trackClick(target) {
this.events.push({
type: 'click',
element: target.tagName,
id: target.id || null,
text: target.innerText || target.value || null,
x: target.getBoundingClientRect().x,
y: target.getBoundingClientRect().y,
timestamp: Date.now()
});
}
trackStayTime() {
const stayTime = Date.now() - this.startTime;
this.events.push({
type: 'stay',
url: window.location.href,
duration: stayTime,
timestamp: Date.now()
});
}
getEvents() {
return this.events;
}
}
实现要点:
- 页面浏览:记录 URL、标题和加载时间。
- 点击事件:针对交互元素(如
<a>
、<button>
),采集位置和内容。 - 停留时间:通过
unload
事件计算页面停留时长。
3:数据上报
在 src/report.js
中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
export class Reporter {
constructor(url) {
this.url = url;
}
send(data) {
const payload = JSON.stringify(data);
if (navigator.sendBeacon) {
navigator.sendBeacon(this.url, payload); // 页面关闭时仍可发送
} else {
fetch(this.url, { method: 'POST', body: payload, keepalive: true });
}
}
}
navigator.sendBeacon
是浏览器提供的一个 JavaScript API,用于异步发送小型数据(如埋点数据)到服务器。它通过 HTTP POST 请求在后台传输数据,即使页面正在卸载(如用户关闭标签页)也能保证发送成功。相比传统的 fetch
或 XMLHttpRequest
,sendBeacon
的优势在于它不阻塞页面关闭,数据发送由浏览器接管,无需等待响应,确保了高可靠性和低性能开销,所以特别适合用户行为统计场景中需要在页面离开时上报数据。
4:整合埋点
在 src/index.js
中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import { BehaviorTracker } from './tracker.js';
import { Reporter } from './report.js';
export class TrackingSDK {
constructor({ reportUrl }) {
this.tracker = new BehaviorTracker();
this.reporter = new Reporter(reportUrl);
this.reportInterval = null;
}
start() {
this.reportInterval = setInterval(() => {
const events = this.tracker.getEvents();
if (events.length > 0) {
this.reporter.send({ events });
this.tracker.events = []; // 清空已发送数据
}
}, 3000); // 每 3 秒上报一次
}
stop() {
clearInterval(this.reportInterval);
this.reporter.send({ events: this.tracker.getEvents() }); // 停止时发送剩余数据
}
track(eventName, properties) {
// 手动埋点接口
this.tracker.events.push({
type: eventName,
properties,
timestamp: Date.now()
});
}
}
5:打包
rollup.config.js
:
1
2
3
4
5
6
7
8
export default {
input: 'src/index.js',
output: {
file: 'dist/tracking-sdk.js',
format: 'umd',
name: 'TrackingSDK'
}
};
1
npx rollup -c
6:使用 SDK
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<body>
<a href="#">Link</a>
<button>Button</button>
<input type="text" placeholder="Input">
<script src="/dist/tracking-sdk.js"></script>
<script>
const sdk = new TrackingSDK({ reportUrl: 'https://example.com/track' });
sdk.start();
// 手动埋点示例
document.querySelector('button').addEventListener('click', () => {
sdk.track('CustomClick', { category: 'test' });
});
</script>
</body>
数据格式示例
上报的数据示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
"events": [
{
"type": "pageview",
"url": "https://example.com",
"title": "Home",
"timestamp": 1604361600000,
"loadTime": 1200
},
{
"type": "click",
"element": "BUTTON",
"id": null,
"text": "Button",
"x": 50,
"y": 100,
"timestamp": 1604361600500
},
{
"type": "stay",
"url": "https://example.com",
"duration": 5000,
"timestamp": 1604361605000
}
]
}
优化与扩展
- 节流优化:高频点击可用
throttle
减少事件量。 - 属性扩展:自动添加设备信息(如屏幕分辨率)。
- 异常处理:捕获 JS 错误并上报。
- 兼容性:为老浏览器(如 IE)添加 polyfill。
数据分析
服务器收到数据后,可以:
- 计算页面 PV(Page View)。
- 分析热门点击区域。
- 评估用户平均停留时间。
This post is licensed under CC BY 4.0 by the author.