前端错误监控
type
status
date
slug
summary
tags
category
icon
password
Blocking
Blocked by
top
URL
Sub-item
Parent item
自研监控优势
为什么不直接用 sentry 私有化部署,而选择自研前端监控?
这是优先要思考的问题,sentry 作为前端监控的行业标杆,有很多可以借鉴的地方
相比 sentry,自研监控平台的优势在于:
1、可以将公司的 SDK 统一成一个,包括但不限于:监控 SDK、埋点 SDK、录屏 SDK、广告 SDK 等
2、提供了更多的错误还原方式,同时错误信息可以和埋点信息联动,便可拿到更细致的用户行为栈,更快的排查线上错误
3、监控自定义的个性化指标:如 long task、memory 页面内存、首屏加载时间等。过多的长任务会造成页面丢帧、卡顿;过大的内存可能会造成低端机器的卡死、崩溃
4、统计资源缓存率,来判断项目的缓存策略是否合理,提升缓存率可以减少服务器压力,也可以提升页面的打开速度
5、提供了 采样对比+ 轮询修正机制 的白屏检测方案,用于检测页面是否一直处于白屏状态,让开发者知道页面什么时候白了,具体实现见 前端白屏的检测方案,解决你的线上之忧
指标
性能监控
字段 | 描述 | 计算公式 | 备注 |
FP | 首次绘制 | responseEnd - fetchStart | 将第一个像素点绘制到屏幕的时刻 |
FCP | 首次内容绘制 | First Content Paint | 首次内容绘制是浏览器将第一个 DOM 渲染到屏幕的时间,可以是任何文本、图像、SVG 等的时间; |
FMP | 首次有意义绘制 | First Meaningful paint | 首次有意义绘制是页面可用性的量度标准; |
TTI | 首次可交互时间 | domInteractive - fetchStart | 浏览器完成所有HTML解析并且完成DOM构建,此时浏览器开始加载资源。 |
DomReady | HTML加载完成时间也就是 DOM Ready 时间。 | domContentLoadEventEnd - fetchStart | 单页面客户端渲染下,为生成模板dom树所花费时间;非单页面或单页面服务端渲染下,为生成实际dom树所花费时间' |
Load | 页面完全加载时间 | loadEventStart - fetchStart | Load=首次渲染时间+DOM解析耗时+同步JS执行+资源加载耗时。 |
FirstByte | 首包时间 | responseStart - domainLookupStart | 从DNS解析到响应返回给浏览器第一个字节的时间 |
卡顿 | ㅤ | ㅤ | 指超过 50ms 的长任务,具体的指标可以根据页面的内容进行调节,一般 50ms 人眼就能感觉到卡顿。 |
耗时监控
字段 | 描述 | 计算公式 | 备注 |
DNS | DNS查询耗时 | domainLookupEnd - domainLookupStart | 如果使用长连接或本地缓存,则数值为0 |
TCP | TCP连接耗时 | connectEnd - connectStart | 如果使用长连接或本地缓存,则数值为0 |
SSL | SSL安全连接耗时 | connectEnd - secureConnectionStart | 只在HTTPS下有效,判断secureConnectionStart的值是否大于0,如果为0,转为减connectEnd |
TTFB | 请求响应耗时 | responseStart - requestStart | TTFB有多种计算方式,相减的参数可以是 requestStart 或者 startTime |
Trans | 内容传输耗时 | responseEnd - responseStart | 无 |
DOM | DOM解析耗时 | domInteractive - responseEnd | 无 |
Res | 资源加载耗时 | loadEventStart - domContentLoadedEventEnd | 表示页面中的同步加载资源。 |
行为监控
- PV、UV量,日同比、周同比等。能清晰的明白流量变化。
- 用户热点页面、高访问量TOP10
- 设备、浏览器语言、浏览器、活跃时间段等的用户特征
- 用户的行为追踪:某个用户,进入了网站后的一系列操作或者跳转行为;
- 用户自定义埋点上报用户行为:想做一些自定义事件的监听,比如播放某个视频的行为动作。
- 多语种站点,每个语种的用户量
错误监控
Error类型
类型 | 含义 | 说明 |
SyntaxError | 语法错误 | 语法错误 |
ReferenceError | 引用错误 | 常见于引用了一个不存在的变量: let a = undefinedVariable; |
RangeError | 有效范围错误 | 数值变量或参数超出了其有效范围。 常见于 1.创建一个负长度数组 2.Number对象的方法参数超出范围: let b = new Array(-1) |
TypeError | 类型错误 | 常见于变量或参数不属于有效类型 let foo = 3;foo(); |
URIError | URL处理函数错误 | 使用全局URL处理函数错误,比如 decodeURIComponent('%'); |
错误监控采集
window.addEventListener('error')
:监听JS代码异常window.onerror
:监听资源加载异常xhr.addEventListener('error')
:监听请求异常等window.addEventListener('unhandledrejection')
: 监听未被捕获的 Promise 错误框架自带的错误监控
react:errorBounry
监控白屏
白屏就是页面上什么东西也没有,在页面加载完成之后,如果页面上的空白点很多,就说明页面是白屏的,需要上报,这个上报的时机是:
document.readyState === 'complete'
表示文档和所有的子资源已完成加载,表示 load(window.addEventListener('load')
)状态事件即将被触发。document.readyState 有三个值:loading(document 正在加载),interactive(可交互,表示正在加载的状态结束,但是图像,样式和框架之类的子资源仍在加载),complete 就是完成,所以监控白屏需要在文档都加载完成的情况下触发。
监控白屏的思路主要是:可以将可视区域中心点作为坐标轴的中心,在 X、Y 轴上各分 10 个点,找出这个 20 个坐标点上最上层的 DOM 元素,如过这些元素是包裹元素,空白点数就加一,包裹元素可以自定义比如 Html Body App Root Container Content 等,空白点数大于 0 就上报白屏日志。
监控卡顿
用户交互的响应时间如果大于某一个时间,用户就会感觉卡顿。可以定一个时间比如 100 毫秒,就代表响应时间长,会卡顿。
PerformanceObserver 构造函数使用给定的观察者 Callback 生成新的 PerformanceObserver 对象,当通过 Observe () 方法注册条目类型(需要监控的类型)的性能条目被记录下来时,会调用该观察者回调。
所以可以 new PerformanceObserver 来监控 longTask,监控的资源加载如果超过 100 毫秒就表示卡顿,可以浏览器空闲(requestIdleCallback)的时候上报数据。
如何计算首屏时间、白屏时间
计算首屏时间和白屏时间的主要方法有:
- 使用 Navigation Timing API
- navigationStart:准备请求页面的时刻
- responseStart:收到第一个字节的时刻
- responseEnd:收到最后一个字节的时刻
- domInteractive:DOM 被解析完成的时刻
- domContentLoadedEventEnd:DOM 被完全加载的时刻
首屏时间 = domContentLoadedEventEnd - navigationStart
白屏时间 = responseEnd - navigationStart
- 使用 Performance API
- performance.getEntriesByName('navigation')[0].responseEnd
- performance.timing.domContentLoadedEventEnd
首屏时间 = domContentLoadedEventEnd - responseEnd
- 通过前端 JavaScript 检测
监听 DOMContentLoaded 事件,记录时间。白屏时间通过检查 body/html 标签可见性实现。
- 使用MutationObserver
- body
- 区域稳定的时间点
性能指标
PerformanceObserver.observe 方法用于观察传入的参数中指定的性能条目类型的集合。当记录一个指定类型的性能条目时,性能监测对象的回调函数将会被调用。performance.timing 记录了从输入 URL 到页面加载完成的所有的时间,从这些字段中可以提取对对页面性能的监控,通过分析这些指标来优化页面的体验,比如统计 FMP、LCP 等,具体可以查看 MDN。
统计 pv (页面的停留时间)
navigator.connection 对象获取网络连接的信息:effectiveType(网络类型),RTT(估算饿往返时间)等,还能通过监听 window.addEventListener ('unload') 事件计算用户在页面的停留时间