[这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天]
1. 什么是前端监控
一个经典面试题: 在浏览器中,从输入 URL 到页面展示,这中间发生了什么
前端监控就是尽可能的收集这一过程中以及后续用户交互中产生的性能指标与发生的异常事件并上报到平台完成消费
2. 为什么需要前端监控
前端监控通过对页面数据的采集和上报,来帮助开发者更快地对质量差的页面进行分析与归因
- 打开网页的速度慢 --- 是否是页面的某个关键资源加载太慢
- 交互卡顿 --- 从 js 的执行线线程出发,是否是页面同步计算的任务太重,导致阻塞了线程
- 资源加载失败 --- 是否是客户端网络状态差,或上游服务节点异常
- 页面白屏 -- 是否是脚本执行失败、关键资源加载失败、请求失败
3. 前端监控到底监控了什么
- 性能指标
- 异常事件
- 用户行为
4. 前端监控之常用性能指标
- 以用户为中心的性能指标
- TTI: 测量页面从开始加载到主要子资源完成渲染,并能够快速、可靠地响应用户输入所需的时间
- TTI 是反映页面可用性的重要指标。 TTI 的值越小,代表用户可以更早地操作页面,用户体验就更好
- SI: 衡量页面可视区域加载速度,帮助检测页面的加载体验差异
- A 和 B 的首次内容出现和完全加载时间是一样的,但是从用户角度出发 A 的体验感更好
- FID
- 测量从用户第一次与页面发生交互直到浏览器做出响应,实际能够开始处理事件时处理程序所经过的时间
- LCP
- 最大内容在可视区内变得可见的时间点(最想要呈现给用户的部分内容)
- 因此,LCP越早,就能让用户最早看见我们想要呈现给用户的内容
- TBT
- 量化主线程在空闲之前的繁忙程度,理解在加载期间,页面无法响应用户输入的时间有多久
- 长任务: 如果一个任务在主线程上运行超过 50 毫秒,那么它就是长任务
- 一个页面的 TBT , 是从 FCP(关键内容加载完毕) 到 TTI(用户最早可以进行交互的时间) 之间所有长任务的阻塞时间之间之和
- CLS
- 量化了在页面加载期间,视口元素的移动速度
- 如果一个页面的元素移动量大,那么 CLS 的值也是非常高的。这对用户的体验并不好,有时还会引发一些用户预料之外的操作
- 指标总结
5. 前端监控之前端常见异常
- 静态资源错误
- 静态资源: 加载页面所需的 html 、 css 和 js 文件,以及多媒体文件
- 在拉取和加载静态资源的过程中发生了网络错误、资源本身地址错误等预料之外的异常,导致资源无法正常的渲染到页面上
- 请求异常
- HTTP 状态码
- 100 - 199 : 信息响应
- 200 - 299 : 成功响应
- 300 - 399 : 重定向信息
- 400 - 499 : 客户端错误响应
- 500 - 599 : 服务端错误响应
- 请求异常相当于请求响应状态码 >= 400
- 状态码 0 是什么
- JS 错误
- 在页面运行时发生的 JS 错误会严重影响页面的正常渲染与交互,是前端监控的重点
- 白屏异常
- 前面几类都可以通过浏览器提供的标准化方法来监听到,而白屏异常没有标准化的监听方法,所以更考验前端监控开发者的功底
- 通常我们可以通过判断 DOM 树的结构来粗略的判断白屏是否发生
- 当监听到白屏发生后,我们还需对白屏的发生进行归因
- 通常导致白屏发生的原因可能有如下几个因素
- 发生 JS 错误导致页面关键资源加载失败
- 请求异常或静态资源加载失败
- 长时间的 JS 线程繁忙阻塞渲染任务
6. 性能指标监控
- 监控的原理
- 利用浏览器提供的标准的对象,比如 Performance 和 PerformanceObserver 可以监控到一些标准的渲染性数据
- JS 错误监听
- 利用 window.addeventListener 的 error 和 unhandledrejection 可以监控到全局的 js 错误
- 在 window.addeventListener 中监听事件类型为 error 的类型的事件可以监控到全局的 js 错误
- unhandledrejection: 当 Promise 被 reject 并且没有 reject 处理器的时候,会触发 unhandledrejection 事件,意味着一些异步任务发生了某些错误
- 静态资源错误监听
- 利用 window.addEventListener 的 error 事件可以监听到静态资源错误,主要注意和 js error 进行区分(在 event 的属性上存在区别)
- 注意,在捕获静态资源错误时,只能在捕获阶段进行捕获
- 请求异常监控
- 通过 hook xhr 和 fetch 对象来监听请求时发生的错误
7. 前端监控流程概述
sdk 主要完成前两步,后两步需要后端服务和平台的支持
- 数据上报
- 专为前端监控打造的请求函数
Navigator.sendBeacon()
- 该方法可用于通过 HTTP POST 将少量数据 异步 传输到 Web 服务器
- 它主要用于发送统计数据到 Web 服务器
8. 如何让 sdk 更加健壮
- 关注请求性能
- 请求异常除了关注请求错误外,我们还要关注慢请求,可以参考 Performance Resources Timing 来获取请求各阶段耗时,找出慢请求
- 慢请求的原因
- 请求体内容太多
- 返回数据量多
- 上游服务发生异常
- 更安全和稳定的 Hook 函数