前端监控

创建
阅读 1444

页面浏览数据收集

在参考其他一些文章后,前端监控要实现收集的数据是: When, Who do What

When 访问时间:

  • 浏览的时刻

Who 客户端信息:

  • 屏幕尺寸
  • 颜色深度
  • 语言
  • 浏览器标识

What 浏览的页面信息:

  • 访问的域名
  • 访问的页面标题
  • 访问的页面 URL 地址
  • 上一个页面的 URL 地址

页面性能数据收集

通过 performance.timing 接口,可以获取页面加载的一些信息。

  • DNS 查找时间
  • tcp 连接时间
  • 首屏加载事件
  • DOM渲染完成所需时间
  • 页面加载加载完成所需时间 (触发 load 事件的时间)

关于 PerformanceTiming 在 MDN 上的文档: https://developer.mozilla.org/zh-CN/docs/Web/API/PerformanceTiming

PS: 因为 performance.timing.loadEventEnd 记录的是 load 事件结束后的时间戳,所以在页面load 之前它的值为0,为了保证数据准确,将上报时机放在 load 之后再 setTimeout 后中执行。如果一个页面还没加载完就被关闭,那这条访问的数据就会遗漏掉。

PPS:通过 new Image 将请求伪装成 image 请求,避免出现跨域请求的问题,传递给后端。

因为访问时间、用户浏览器标识,在HTTP请求的时候,后端可以自行获取,就不在前端获取,再传给后端了。

完整代码如下:

window.onload = function () {
  setTimeout(() => {
    const params = {};

    // document
    if (document) {
      params.domain = document.domain || '';
      params.url = document.URL || '';
      params.title = document.title || '';
      params.referrer = document.referrer || '';
    }

    // window
    if (window && window.screen) {
      params.sh = window.screen.height || 0;
      params.sw = window.screen.width || 0;
      params.cd = window.screen.colorDepth || 0;
    }

    // navigator
    if (navigator) {
      params.lang = navigator.language || '';
    }

    // performance time
    const t = performance.timing;
    const start = t.navigationStart;
    let dnsTime = 0;
    let tcpTime = 0;
    let firstPaintTime = 0;
    let domRenderTime = 0;
    let loadTime = 0;

    dnsTime = t.domainLookupEnd - t.domainLookupStart;
    tcpTime = t.connectEnd - t.connectStart;
    firstPaintTime = t.responseStart - start;
    domRenderTime = t.domContentLoadedEventEnd - start;
    loadTime = t.loadEventEnd - start;

    params.dnsTime = dnsTime;
    params.tcpTime = tcpTime;
    params.firstPaintTime = firstPaintTime;
    params.domRenderTime = domRenderTime;
    params.loadTime = loadTime;

    // 拼接参数
    let args = '';
    for (const key in params) {
      if (Object.prototype.hasOwnProperty.call(params, key)) {
        if (args !== '') {
          args += '&';
        }
        args += `${key}=${params[key]}`;
      }
    }
    // 通过伪装成 Image 对象,传递给后端
    const img = new Image(1, 1);
    const src = `/v1/stat?args=${encodeURIComponent(args)}`;
    img.src = src;
  }, 0);
};

参考文档

  1. PerformanceTiming
  2. 前端监控和前端埋点

本文链接 https://www.yidiankuaile.com/post/frontend-monitor

最后更新