数据埋点
- 数据采集领域的术语,指的是针对用户行为或特定事件进行捕获、处理和发送的相关技术及其实施过程,是对特定事件或者用户行为的数据监控和数据上传。
数据类型
- 我们从三个维度出发去监控一个项目,即系统所面向的某一个主体,系统单个局部面向使用不同使用主体的差异的情况监控,系统面向运行过程的总体统筹监控这三个方面;也就是用户的行为,页面的性能,产品的异常。
从而我们可以划分三个类别出来:
1、数据监控(涉及用户行为及其相应的事件)
2、性能监控(涉及页面的性能及渲染交互)
3、异常监控(涉及产品系统的运行时异常)
同时我们可以给出一个大致的数据结构范围:
pv:页面访问量
uv:用户访问量
关于用户的自定义事件
关于页面性能加载数据
报错的异常信息
前端埋点方式
了解了怎样前端埋点的相关概念,下面说说埋点有哪些方式,也就是可以使用哪些方式来做埋点的数据监控。
一、 XMLHttpRequest
这种使用方式其实就是约定一个接口,然后通过提交请求去进行数据上报的,如:
function buryingPoint(data) {
return new Promise((resolve, reject) => {
// 创建XMLHttpRequest
const xhr = new XMLHttpRequest();
// 定义请求接口
xhr.open("post", '/buryingPoint', true);
// 发送数据
xhr.send(data);
});
}
let info = {}
buryingPoint(info) // 这样就成功上报了info的对象
当我们去调用这个buryingPoint方法时,也就将数据进行了服务端的上报了。
但是,这种传统方式的请求埋点,一般会存在跨域的风险,并且他必须是同步的,否则会容易中断请求。
二、 script及link
通过以传统的请求方式进行数据埋点我们可以看出,实现数据上报并不强调前后端的交互的,因此我们也可以通过一些支持跨域的标签去实现数据上报功能。如:
let a = document.createElement('script')
a.src = 'https://www.test.com/web/buryingPoint/test.js?test=123'
document.body.appendChild(a)
- 创建一个script标签,src地址后面带上我们需要传递的数据,并将这个标签挂载中页面,这样就实现script+link方式的数据上报。
- 使用script标签还有一个好处就是,它是兼容的,可以适应不同的浏览器。
- 但是,这种方式也有缺点,那就是需要挂载到页面上,而反复操作dom会造成页面性能受影响,并且载入js/css资源还会阻塞页面渲染,影响用户体验,频繁上报是不适合这种方式的。
三、 img
不同于script标签,使用img标签的好处是,无需挂载到页面上,反复操作dom;而且img的加载不会阻塞html的解析,img加载后并不渲染,它需要等待Render Tree生成完后才和Render Tree一起渲染出来。
注意:通常埋点上报会使用 gif 图,合法的 gif 图只需要 43 个字节
如:
function buryingPoint(src) {
var img = document.createElement("img");
img.src = src;
}
buryingPoint('https://www.test.com/web/buryingPoint/test.gif?test=123')
我们除了img标签还可以使用new image(),设置其src之后就可以直接请求图片。
四、 Navigator.sendBeacon
Navigator.sendBeacon是目前通用的埋点上报方案,Navigator.
sendBeacon方法接受两个参数,第一个参数是目标服务器的 URL,第二个参数是所要发送的数据(可选),可以是任意类型(字符串、表单对象、二进制对象等等)。
过去,为了解决这个问题,统计和诊断代码通常要在
- 发起一个同步 XMLHttpRequest 来发送数据。
- 创建一个 元素并设置 src,大部分用户代理会延迟卸载(unload)文档以加载图像。
- 创建一个几秒的 no-op 循环。
上述的所有方法都会迫使用户代理延迟卸载文档,并使得下一个导航出现的更晚。下一个页面对于这种较差的载入表现无能为力。
这就是 sendBeacon() 方法存在的意义。使用 sendBeacon() 方法会使用户代理在有机会时异步地向服务器发送数据,同时不会延迟页面的卸载或影响下一导航的载入性能
这意味着:
- 数据发送是可靠的。
- 数据异步传输。
- 不影响下一导航的载入。
数据是通过 HTTP POST 请求发送的。
如:
function buryingPoint(url, data) {
navigator.sendBeacon(url, data)
}
buryingPoint('https://www.test.com/web/buryingPoint',{time: Date.now()})
目前最合适的数据上传方案是navigator.sendBeacon,不仅是异步的,而且不受同域限制,而且作为浏览器的任务,因此可以保证会把数据发出去,不影响页面卸载。
常见前端埋点
列举一些常见的前端埋点:
1、点击触发埋点
绑定用户行为触发的点击事件,当点击目标元素,触发埋点的数据上报。
function clickButton(url, data) {
navigator.sendBeacon(url, data)
}
2、内容可见埋点
通过交叉观察器去监听当前元素是否出现在页面。
// 可见性发生变化后的回调
function callback(data) {
navigator.sendBeacon(url, { target: data[0].target, text: '内容可见' })
}
// 交叉观察器配置项
let options = {};
// 生成交叉观察器
const observer = new IntersectionObserver(callback);
// 获取目标节点
let target = document.getElementById("target");
// 监听目标元素
observer.observe(target);
3、页面停留时间上报埋点
路由文件中,初始化一个startTime,当页面离开时通过路由守卫计算停留时间。
let url = ''// 上报地址
let startTime = Date.now()
let currentTime = ''
router.beforeEach((to, from, next) => {
if (to) {
currentTime = Date.now()
stayTime = parseInt(currentTime - startTime)
navigator.sendBeacon(url, {time: stayTime})
startTime = Date.now()
}
})
4、错误监听埋点
通过监听函数去接收错误信息。
// vue错误捕获
app.config.errorHandler = (err) => {
navigator.sendBeacon(url, {error: error.message, text: 'vue运行异常' })
}
// JS异常与静态资源加载异常
window.addEventListener('error', (error) => {
if (error.message) {
navigator.sendBeacon(url, {error: error.message, text: 'js执行异常' })
} else {
navigator.sendBeacon(url, {error: error.filename, text: '资源加载异常' })
}
}, true)
// 请求错误捕获
axios.interceptors.response.use(
(response) => {
if (response.code == 200) {
return Promise.resolve(response);
} else {
return Promise.reject(response);
}
},
(error) => {
// 返回错误逻辑
navigator.sendBeacon(url, {error: error, text: '请求错误异常' })
}
);
标签:url,前端,buryingPoint,sendBeacon,error,埋点,上传,页面
From: https://www.cnblogs.com/lyly96720/p/18030042