2. 前端埋点数据收集和上报方案

189 阅读3分钟

埋点分为业务埋点和技术埋点; 业务埋点保留着产品想要收集的用户行为,技术埋点监控前端代码报错性能指标

监控方案:

代码报错:

  1. addEventListen('error') :监控资源加载失败错误
  2. window.onError:监控js执行报错
  3. addEventListen('unHandledrejection'):监控promise 错误,但是没有发生错误的列数行数

性能指标:

指标名描述
FP页面首次绘制时间
FCP页面首次有内容绘制的时间
FMP页面首次有效绘制时间,FMP >= FCP
TTI页面完全可交互时间
FID页面加载阶段,用户首次交互操作的延时时间
MPFID页面加载阶段,用户交互操作可能遇到的最大延时时间
LOAD页面完全加载的时间(load 事件发生的时间)

如何实现监控:window.performence API

计算FP: performance.getEntriesByType('paint') 中找到name为first-paint:
计算FCP:同上,找到name为first-contentful-paint:

计算FMP:先定义好有效内容,找到有效内容的dom,使用MutationObserver监听有效内容显示的时间戳fmpTime,使用performace.getEntriesType('paint').timing.fetchStart - fmpTime计算:
// 创建一个 MutationObserver 实例
const observer = new MutationObserver((mutationsList, observer) => {
    // 遍历每一个发生的变化
    for (let mutation of mutationsList) {
        // 检查是否有节点被添加到DOM中
        if (mutation.type === 'childList') {
            // 这里可以进一步检查添加的节点是否是有意义的内容,根据你的具体情况来判断
            // 如果有意义的内容被添加到页面上,则记录FMP时间点
            const fmpTime = performance.now();
            console.log('FMP时间点:', fmpTime);
            // 在这里你可以将FMP时间点传递给其他地方进行处理,比如报告或者分析
            // 然后断开MutationObserver的观察
            observer.disconnect();
            break; // 一旦找到有意义的内容被添加,停止遍历变化列表
        }
    }
});

// 监视子节点的添加
observer.observe('有效内容DOM', {
    childList: true, // 监听 target 节点中发生的节点的新增与删除
    subtree: true // 将会监听以 target 为根节点的整个子树
});

上报方案:

在这个场景中,需要考虑两个问题:

  • 如果数据上报接口与业务系统使用同一域名,浏览器对请求并发量有限制,所以存在网络资源竞争的可能性。
  • 浏览器通常在页面卸载时会忽略异步ajax请求,如果需要必须进行数据请求,一般在unload或者beforeunload事件中创建同步ajax请求,以此延迟页面卸载。从用户侧角度,就是页面跳转变慢。
  1. 如何解决网络资源竞争问题:

将埋点分类:

  • pv、用户行为、错误属于即时上报
  • 性能数据 需要等到页面加载完成,数据采集完成上报
  • API请求数据会进行本地缓存,达到阈值或页面可见性变化或页面退出时上报
  1. 如何解决页面卸载数据丢失的问题
  • Beacon API :Beacon 接口用来调度向 Web 服务器发送的异步非阻塞请求。

    • Beacon 请求使用 HTTP POST方法,并且不需要有响应。
    • Beacon 请求能确保在页面触发 unload 之前完成初始化。
  • Image

    • 由于img图片为get请求方式,不同服务器针对uri的长度有限制,长度超过限制时会出现HTTP 414错误,所以还要注意上报频率,减少一次性上传的属性过多。

综上,实际业务可以优先考虑Beacon API,Image作为fallBack使用:

function sendLog(url: string, params: object) {
    if(navigator.sendBeacon) {
        sendBeacon(url, params)
    } else {
        sendImage(url, params)
    }
}

前端埋点数据收集及上报方案:cloud.tencent.com/developer/a…

mutationObserver文档:developer.mozilla.org/zh-CN/docs/…