这是我参与「第四届青训营 」笔记创作活动的第2天
一、前端监控流程
暂时无法在飞书文档外展示此内容
数据采集
- PV监控:页面切换后新的url、页面切换原因
- JS错误:错误对应类型、描述、行列号、堆栈,错误发生前的用户交互、错误的上下文等等
- 性能监控:首屏加载各阶段耗时、各性能指标、SPA切换耗时、longtask等等
- 请求监控:请求的路径、状态码、请求头和响应头、请求各阶段耗时等等
- 白屏监控:白屏发生的页面、关联的异常、相关的上下文等等
- 静态资源监控&&用户行为监控&&自定义监控...
组装上报
- 基础信息包装:页面路径、页面标识、全局context、部署版本、部署环境、网络等等
- 采样逻辑
- 用户自定义包装逻辑执行:比如补充更多上下文、数据脱敏等·队列暂存&&聚合发送
- sendBeacon:在页面关闭时发送请求,不阻塞页面卸载
清洗存储
- User-Agent解析:浏览器版本、系统版本、机型、设备品牌等等IP解析:地区、省份、城市、运营商、地理位置等等
- 分类型落表落库
- 处理JS错误:堆栈归一化、堆栈反解析
- Clickhouse存储
数据消费
- 总览分析
- 各功能模块消费视角&&多维分析
- 单点查询,针对用户全生命周期上报数据的重建展示
- 数据订阅&&实时报警
- issue管理&&归因分析
二、前端监控关注点
三、以技术为中心的性能指标
通过记录一个文档从发起请求到加载完毕的各阶段的性能耗时,以加载速度来衡量性能。
这是W3C Performance Timeline Level 2 的模型图图中很多的时间点、时间段,对于用户来说或许并不需要知道,但是 对于技术人员来说 ,采集其中有意义的时间段,做成瀑图,可以让我们**从精确数据的角度**对网站的性能有一个定义,有一个优化的方向;
// 关键时间点
FP: responseEnd - fetchStart, // 首次渲染耗时 白屏时间 加载文档到第一帧非空图像的时间
TTI: domInteractive - fetchStart, // 首次可交互时间
DomReady: domContentLoadedEventEnd - fetchStart, // DOM阶段渲染耗时
Load: loadEventStart - fetchStart, // 页面完全加载时间
FirstByte: responseStart - domainLookupStart, // 首包时间耗时 DNS解析到响应返回给浏览器第一个字节的时间
// 关键时间段
DNS: domainLookupEnd - domainLookupStart, // DNS解析耗时
TCP: connectEnd - connectStart, // TCP建立连接耗时
SSL: secureConnectionStart ? connectEnd - secureConnectionStart : 0, //数据安全连接耗时
TTFB: responseStart - requestStart, //网络请求耗时
Trans: responseEnd - responseStart, // 响应数据传输耗时
DomParse: domInteractive - responseEnd, // DOM解析耗时
Res: loadEventStart - domContentLoadedEventEnd, // 资源加载耗时
这里去调用window提供的Performance接口可以获取到当前页面中与性能相关的信息,getEntriesByType()方法返回给定类型的PerformanceEntry 列表,(这里类型就是navigation ,调用这个方法可填的其他类型还有frame, resource, mark, measure, paint)PerformanceEntry 对象代表了 performance 时间列表中的单个 metric(公制) 数据。Performance entries 在资源加载的时候,也会被动生成(例如图片、script、css 等资源加载)
const navigation = performance.getEntriesByType('navigation').length > 0
? performance.getEntriesByType('navigation')[0]
: performance.timing; // W3C Level1 (目前兼容性高,仍然可使用,未来可能被废弃)。
\
四、以用户为中心的性能指标
-
FP (First Paint) :首次渲染的时间点。FP时间点之前,用户看到的都是没有任何内容的白色屏幕。(白屏)
-
performance.getEntriesByName('first-paint');
-
-
FCP(First Contentful Paint) :首次有内容渲染的时间点。在用户访问Web网页的过程中,FCP时间点之前,用户看到的都是没有任何实际内容的屏幕。FCP反映当前Web页面的网络加载性能情况、页面DOM结构复杂度情况、inline script 的执行效率的情况。当所有的阶段性能做的非常好的情况下,首次出现内容的时间就会越短,用户等待的时间就会越短,流失的概率就会降低。(灰屏)
-
performance.getEntriesByName('first-contentful-paint');
-
-
FMP(First Meaningful Paint) ︰首次绘制有意义内容的时间点。
- 当整体页面的布局和文字内容全部渲染完成后,可认为是完成了首次有意义内容的绘制。FMP通常被认为是用户获取到了页面主要信息的时刻,也就是说此时用户的需求是得到了满足的,所以产品通常也会关注FMP指标。(首屏)
- SI(Speed lndex) :衡量页面可视区域加载速度,帮助检测页面的加载体验差异。
- TTI(Time to Interactive): 测量页面从开始加载到主要子资源完成渲染,并能够快速、可靠地响应用户输入所需的时间。TTI 反映页面可用性的重要指标。TTI 值越小,代表用户可以更早地操作页面,用户体验就更好。
-
FID(First Input Delay): 测量从用户第一次与页面交互(比如当他们单击链接、点按按钮等等)直到浏览器对交互作出响应,实际能够开始处理事件 处理程序所经过的时间。
-
new PerformanceObserver((entryList, observer) => { entryList.getEntries().forEach(callback); //不再观察了 keepObserver || observer.disconnect() }).observe({ entryTypes: ['first-input'] })
-
这里是用性能检测对象PerformanceObserver监测性能度量事件,在浏览器的性能时间轴记录下一个新的 performance entries 的时候将会被通知 。
以上指标归纳为这几个方面:
加载速度决定了 用户是否可以尽早感受到页面已经加载完成
视觉稳定衡量了 页面上的视觉变化对用户造成的负面影响大小
交互延迟决定了 用户是否可以尽早感受到页面已经可以操作
五、全新性能指标
- LCP(Largest Contentful Paint) : 最大的内容在可视区域内变得可见的时间点。(大概就是让你理解页面内容的最有用的元素)
new PerformanceObserver((entryList, observer) => {
entryList.getEntries().forEach(callback);
//不再观察了
keepObserver || observer.disconnect()
}).observe({ entryTypes: ['largest-contentful-paint'] })
| 指标 | 定义 | 存在的问题 |
|---|---|---|
| FCP | 首次内容绘制时间 | 通常与用户无关 |
| FMP | 首次绘制有意义内容的时间点 | 非标准化并且难以在浏览器之间统一实现约20%的情况下不准确。 |
| SI | 跟踪在视口中加载内容的视觉进程 | 复杂的指标,难以解释。计算密集,不可用于线上监控。 |
LCP则不同:
- 给出与FMP相似的结果
- 容易理解
- 容易计算和上报
- TBT(Total Blocking Time): 量化主线程在空闲之前的繁忙程度,有助于理解在加载期间,页面无法响应用户输入的时间有多久。
- CLS(Cumulative Layout Shift): 量化了在页面加载期间,视口中元素的移动程度
这里为什么没有FMP、TBT和SI呢?
经过测试,LCP非常近似于FMP的时间点,FMP渐渐可以通过LCP代替。SI的计算逻辑比较复杂,更常用在lighthouse中,而非线上监控。
虽然TBT可以在线上进行测量,但不建议这样做,因为用户交互会影响网页的TBT,从而导致报告中出现大量差异,线上监控推荐使用FID。
六、页面性能监控
Navigation Timing:提供了文档导航过程中完整的计时信息,即一个文档从发起请求到加载完毕各阶段的性能耗时。
//用这个api获得
window.performance.getEntries()[0]
Resource Timing:提供文档中资源的计时信息。
//用这个api获得
window.performance.getEntries()[1]
PerformanceEntry 对象
对象代表了 performance 时间列表中的单个 metric 数据。