标签
note
字数
787 字
阅读时间
4 分钟
数据埋点其实要考虑的就是 用户行为、错误警告、页面性能 三个核心方面
SDK 核心代码
js
let SDK = null // EasyAgentSDK 实例对象
const QUEUE = [] // 任务队列
const NOOP = (v) => v
// 通过 web-vitals 页面性能指标
const reportWebVitals = (onPerfEntry) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry) // 布局偏移量
getFID(onPerfEntry) // 首次输入延迟时间
getFCP(onPerfEntry) // 首次内容渲染时间
getLCP(onPerfEntry) // 首次最大内容渲染时间
getTTFB(onPerfEntry) // 首个字节到达时间
})
}
}
export default class EasyAgentSDK {
appId = ''
baseUrl = ''
timeOnPage = 0
config = {}
onPageShow = null
onPagesHide = null
constructor(options = {}) {
if (SDK) return
SDK = this
this.appId = options.appId
this.baseUrl = options.baseUrl || window.location.origin
this.onPageShow = options.onPageShow || NOOP
this.onPagesHide = options.onPagesHide || NOOP
// 初始化监听页面变化
this.listenPage()
}
// 设置 config
setConfig(congfig){
this.config = congfig
}
// 刷新任务队列
flushQueue() {
Promise.resolve().then(() => {
QUEUE.forEach((fn) => fn())
QUEUE.length = 0;
})
}
// 监听页面变化
listenPage() {
let pageShowTime = 0
window.addEventListener('pageshow', () => {
pageShowTime = performance.now()
// 页面性能指标上报
reportWebVitals((data) => {
this.performanceReport({ data })
})
// 执行 onPageShow
this.onPageShow();
})
window.addEventListener('pagehide', () => {
// 记录用户在页面停留时间
this.timeOnPage = performance.now() - pageShowTime
// 刷新队列前执行 onPagesHide
this.onPagesHide();
// 刷新任务队列
this.flushQueue();
})
}
// Json 转 FormData
json2FormData(data){
const formData = new FormData()
Object.keys(data).forEach(key => {
let value = null;
if(value instanceof Blob){
value = data[key];
}else {
value = JSON.stringify(data[key]);
}
formData.append(key, value);
});
return formData
}
// 自定义上报类型
report(config) {
QUEUE.push(() => {
const formData = json2FormData({
...this.config,
...config,
time: new Date().toLocaleString(),
appId: this.appId,
pageUrl: window.location.href,
});
navigator.sendBeacon(`${this.baseUrl}${config.url || ''}`, formData)
})
}
// 用户行为上报
actionReport(config) {
this.report({
...config,
type: 'action',
})
}
// 网络状况上报
networkReport(config) {
this.report({
...config,
type: 'network',
})
}
// 页面性能指标上报
performanceReport(config) {
this.report({
...config,
type: 'performance',
})
}
// 错误警告上报
errorReport(config) {
this.report({
...config,
type: 'error',
})
}
}上报用户行为
统计 PV 和 UV — 自动触发埋点
关于 PV 和 UV 在上述已经做过介绍了,本质上这两个数据统计都可在一个上报类型为 action 数据发送中获得,主要看监控系统是按照怎样的规则对数据进行分析和统计,这里在 SDK 内部监听了页面的 pageshow / pagehide 两个事件:
在
pageshow中可以上报与 PV / UV 相关的数据 和 页面性能相关的数据jswindow.SDK = new EasyAgentSDK({ appId: 'application_id', baseUrl: '//aegis.example.com/collect', onPageShow() { window.SDK.actionReport({ data: {} // 其他必要传递的信息 }) } }); window.SDK.setConfig({ userId: UserInfo.userId, // 当前用户 id userName: UserInfo.userName, // 当前用户 name }); 复制代码在
pagehide中主要用于计算用户停留在页面上的时间timeOnPage和 刷新任务队列
统计用户点击按钮 — 交互式触发埋点
假设我们希望记录某些按钮的使用次数的数据,可以在 document 上监听 click 事件,目的利用事件冒泡以便于不需要侵入不同按钮的 click 事件,比如:
js
const TargetElementFilter = ['export_btn']
const findTarget = (filters) => {
return filters.find((filter) => TargetElementFilter.find((v) => filter === v)));
}
document.addEventListener('click', (e) => {
const { id, className, outerHTML } = e.target
const isTarget = findTarget([id, className])
if (isTarget) {
SDK.actionReport({
data: {
id,
className,
outerHTML
}, // 其他必要传递的信息
})
}
})