前端埋点和监控

前端监控分为三个方向:数据监控、性能监控、异常监控

数据监控

  • 常见的监控数据包括:PV/UV、页面停留时长、通过什么入口进入、在页面触发了什么行为等
  • 代表着:who(uuid)、when(time)、from where(referrer)、where(x,y)、what(自定义拓展数据)串成的用户行为路径

性能监控

  • 具体指标:首屏加载时间、页面的白屏时间、静态资源下载时间等数据

异常监控

  • 前端代码在执行过程中可能会发生异常。包括:静态资源加载异常、js 执行异常等

性能监控

前端埋点和监控

  • 指标信息具体解读 link

首次进入数据

是通过获取performance.timeing/.getEntriesByType('navigation')来获取各节点的执行时间值

  • 各个时间点具体计算方式
// 白屏时间
// 请求开始到解析第一个 html 文档的时间
times.fp = p.responseEnd - p.fetchStart;
// 首次可交互时间
// 完成 html 解析并完成 dom 构建,之后开始加载资源
times.tti = p.domInteractive - p.fetchStart;
// html 加载完成时间
// 这时 js/css 还没有加载完
times.ready = p.domContentLoadedEventEnd - p.fetchStart;
// 页面完成加载完时间
// 为 首次渲染时间+DOM解析耗时+同步JS执行+资源加载耗时
times.load = p.loadEventStart - p.fetchStart;
// 首包时间
// 从DNS解析到响应返回给浏览器第一个字节的时间
times.firstbyte = p.responseStart - p.domainLookupStart;

// dns查询耗时
times.dns = p.domainLookupEnd - p.domainLookupStart;
// dns缓存耗时
times.dnscache = p.domainLookupStart - p.fetchStart;
// tcp连接耗时
times.tcp = p.connectEnd - p.connectStart;
// 请求响应耗时
times.ttfb = p.responseStart - p.requestStart;
// 内容传输耗时。如:js/css 等资源
times.trans = p.responseEnd - p.responseStart;
// DOM解析耗时
times.dom = p.domInteractive - p.responseEnd;
// 资源加载耗时
times.res = p.loadEventStart - p.domContentLoadedEventEnd;
// SSL安全链接耗时
times.ssl = p.connectEnd - p.secureConnectionStart;
// 重定向耗时
times.redirect = p.redirectEnd - p.redirectStart;
// 上个页面卸载耗时
times.unload = p.unloadEventEnd - p.unloadEventStart;

资源加载

对与进入页面后的资源文件加载情况获取。如:script/link/img等可通过PerformanceObserver/MutationObserver来获取相关时间数据

  • PerformanceObserver 创建一个类型为entryType: ['resource']的资源监听对象来获取各文件的加载详细信息
    • 通过performance.getEntriesByType('resource')获取资源列表
  • MutationObserver 来创建对DOM树的深层监听,判断新插入树的节点变化从而获取相关资源的加载信息(不如上面来的全面)
    • 通过对window.document设置监听,来获取添加的节点对象。并在监听它们的load事件来获取资源加载信息

数据监控

事件上报

主要是对全局的click进行监听,并按情况触发上报信息

  • 通过触发的event事件对象,获取path事件触发路径(没有就沿着node.parentElement向上查找)
  • 之后从path获取配置了特定属性的对象进行params上报参数读取。如:data-wit-click

pv监控

分为页面停留时间及路由变化监听

  • 停留时间:通过window.onload/onbeforeunload事件监听来获取之间的时间差,判断用户页面停留时间
  • 路由变化监听
    • 支持history时就对h.pushState/.replaceState()进行拦截重写。来获取API触发时的路由信息。同时再添加popstate事件监听来获取浏览器前进/后退动作
    • 对于hash模式只能添加hashchange事件监听,来获取url的变化
    • 这里需要注意hash的变化也是会触发popstate事件的,所以上面两个事件同时只能监听一个
  • 上报数据信息
    • 主要是url/referer/action/params等信息
    • action 获取时可通过history.length来判断新增,还是前进/后退。这里要注意只有新进栈的才能改变history长度,而浏览器的前进/回退并不改变
    • referer 可通过performance.navigation来获取页面的加载方式。也要注意兼容性处理是否可使用 performance v2 标准

异常监控

异常拦截

主要分为5种形式:资源加载、js报错、promise未捕获、console.error、xhr错误

  • 资源及JS window.addEventListener('error', callback, true) 使用捕获模式获取资源加载错误
  • Promise 异常 window.addEventListener('unhandledrejection')
  • 拦截 console.error 以获取部分框架内抛出的错误
  • 拦截xhr.open()来获取method/url,拦截xhr.send()在内部监听readystatechange事件从而获取readyState/status/responseText

数据发送

默认使用navigator.sendBeacon(),不支持时使用new Image()方式

  • sendBeacon 使用post方式,可发送更多格式的数据并支持跨域。但不支持手动更改headers
  • image 使用 urlParams 方式发送数据,所有要注意数据长度控制

设备信息

主要从navigator/window.screen/document.documentElement等获取信息

  • nav.vendor/platform/userAgent
  • scr.width/height/orientation
  • clientWidth/clientHeight

身份判断

生成uuid存入cookie中(默认30分钟,并在上报信息时刷新时间),当用户登陆后发送请求时会自动携带cookie这时就之前的数据关联并可以确认身份了

  • uuid可使用y-m-d h-m-s-ms来生成,并用随机数补全32位(16进制)

或是添加setUserId()的函数方法,在用户登陆后往上报的数据中手动添加相关的用户身份凭证