前端监控SDK | 青训营笔记

120 阅读8分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 6 天

前端监控SDK

开篇:为什么我们要聊前端监控

什么是前端监控

经典面试题:在浏览器里,从输入 URL 到页面展示,这中间发生了什么?

前端监控就是尽可能的采集这一过程以及后续用户交互中产出的性能指标与发生的异常事件并上报到平台完成消费

为什么需要前端监控

前端监控通过对页面数据的采集和上报,来帮助开发者更快速地对质量差的页面进行分析与归因。

研究还表明,性能不佳会对业务目标产生负面影响。例如,BBC 发现他们的网站加载时间每增加一秒,他们就会失去 10% 的用户。

前端监控到底监控了什么

  • 性能指标
  • 异常事件
  • 用户行为

重要指标:

  • 可交互性

    • 卡顿监控:通常由业务逻辑引起,关联用户行为可定位问题
    • 请求性能:长期关注,异动分析,以此为基准衡量服务端性能
  • 服务稳定性

    • 请求成功率:主要关注页面级别和接口级别两个维度,需要具备衡量基准
  • 加载速度

    • 首屏性能:智能归因,根据 timing 各阶段耗时,明确得出可优化的阶段,指导优化
  • 可用性

    • 渲染错误/白屏:关联异常类数据,包括 JS 错误,静态资源错误、请求错误等等
    • 请求错误:长期关注错误率的变更,衡量产品质量。短期关注波动,关联线上问题
    • JS 错误:sourcemap 反解 && issue 管理
    • 静态资源错误:拨测归因,着重展示能定位到问题的静态资源,降低噪音
  • 业务数据

    • PV / UV:用户分析、留存、转化
    • 自定义事件 / 打点

概述:前端监控之常用性能指标

web 性能标准的诞生

早期网页是纯静态的,但随着Web 爆发式发展,页面交互越来越复杂。开发者开始思考如何提高 Web 性能、改善用户体验。因此,2010 年 8 月,W3C 成立了 Web 性能工作组,由来自 Google 和 Microsoft 的工程师担任主席,目标是制定衡量 Web 应用性能的方法和 API。随后,Web 性能工作组开始制定一系列 Web 性能标准,应用到桌面和移动浏览器以及其他环境中,帮助 Web 开发人员评估和理解应用的性能特征

传统的性能指标

传统的性能指标主要依赖 Navigation Timing 或者 Navigation Timing 2,通过记录一个文档从发起请求到加载完毕的各阶段的性能耗时,以加载速度来衡量性能。

以用户为中心的性能指标

传统的性能指标专注于容易衡量的技术细节,但是它们很难反应出用户所真正关心的是什么。如果你仅仅是把加载速度优化的更快,你很快就会发现网站的用户体验依然很差。这就是创建用户为中心的性能指标的原因,它们专注于用户视角下的浏览体验。

用户体验指标
发生了吗?FP (First Paint ),FCP (First Contentful Paint )
内容有用吗?FMP (First Meaningful Paint ),SI (Speed Index),LCP(Largest Contentful Paint )
内容可用吗?Time to Interactive (TTI),TBT (Total Blocking Time)
内容可用吗?First Input Delay (FID),CLS (Cumulative Layout Shift)

Paint.png

FP (First Paint) : 首次染的时间点。 FP 时间点之前,用户看到的都是没有任何内容的白色屏幕

FCP (First Contentful Paint) : 首次有内容染的时间点

EMP(First Meaningful Paint) : 首次绘制有意义内容的时间点

TTI (Time to Interactive) : 测量页面从开始加载到主要子资源完成渲染并能够快速、可靠地响应用户输入所需的时间。TTI 反映页面可用性的重要指标。TTI 值越小,代表用户可以更早地操作页面,用户体验就更好

SI (Speed Index): 衡量页面可视区域加载速度,帮助检测页面的加载体验差异

FID (First Input Delay) : 测量从用户第一次与页面交互 (比如当他们单击链接.纸按按钮等等)直到浏览器对交互作出响应,实际能够开始处理事件时处理程序所经过的时间

LCP (Largest Contentful Paint) : 最大的内容在可视区域内变得可见的时间点。优点: 1.容易理解;2.给出与FMP相似的结果;3.容易计算和上报。

TBT (Total Blocking Time) : 量化主线程在空闲之前的繁忙程度,有助于理解在加载期间,页面无法响应用户输入的时间有多久

长任务:如果一个任务在主线程上运行超过 50 毫秒,那么它就是长任务。超过50ms 后的任务耗时,都算作任务的阻塞时间。一个页面的 TBT,是从 FCP 到 TTI 之间所有长任务的阻塞时间的总和。

CLS (Cumulative Layout Shift) : 量化了在页面加载期间,视口中元素的移动程度 。

概述:前端监控之前端常见异常

静态资源请求错误

静态资源:加载页面所需的 html、css 和 js 等文件,以及其他各类多媒体文件,如图片、音频和视频等。 静态资源错误:在拉取和加载静态资源的过程中发生了预期之外的错误,如网络异常等,导致静态资源无法正常渲染到页面上。

请求错误

Http 请求状态码分类:

  • 100 - 199 -> 信息响应
  • 200 - 299 -> 成功响应
  • 300 - 399 -> 重定向消息
  • 400 - 499 -> 客户端错误响应
  • 500 - 599 -> 服务端错误响应

请求异常 = 请求响应状态码 >= 400 对于通过异步请求拉取的静态资源错误也可选择归纳到请求异常

请求成功率 = 请求成功数 / ( 请求成功数 + 请求失败数 )

JS 错误

在页面运行时发生的 JS 错误会严重影响页面的正常渲染与交互,是前端监控的重点

白屏异常

前面几类异常都可以通过浏览器提供的标准化方法来监听到,而白屏异常没有标准化的监听方法,所以更考验前端监控开发者的功底。通常我们可以通过判断 DOM 树的结构来粗略的判断白屏是否发生。

监听到白屏发生后,我们还需要对白屏的发生进行归因,通常导致白屏发生的原因可能有如下几点:

  1. 发生 JS 错误导致关键资源渲染失败
  2. 请求异常或静态资源加载失败
  3. 长时间的 JS 线程繁忙阻塞染任务

小试牛刀:监控前端性能与异常

性能指标监控

利用 Performance 和 可以监控到 PerformanceObserver 一些标准的渲染性能数据

示例:

/**
 * paint - 监控 fp 和 fcp 
 * largest-contentful-paint 监控 lcp
 * first-input 监控 fip
 *
 *//* 列举出性能指标对应的 entry type
 * fp,fcp --> paint
 * lcp --> largest-contentful-paint
 * fip --> first-input
 */
const entryTypes = ['paint', 'largest-contentful-paint', 'first-input']
​
// 1.通过 PerformanceObserver 监听
const p = new PerformanceObserver(list => {
    for (const entry of list.getEntries()) {
        console.log(entry);
    }
})
p.observe({ entryTypes });
​
// 2. 也可以通过 window.performance 对象拿到 fp fcp 和 fip。
// 注意如果同步打印他们是取不到值的,想想为什么?
window.performance.getEntriesByType('paint');
window.performance.getEntriesByType('first-input');
​
// 3. 封装成一个 monitor
function createPerfMonitor(report: ({ name: string, data: any }) => void){
    const name = 'performance';
    const entryTypes = ['paint, 'largest-contentful-paint', 'first-input'];
    function start() {
        const p = new PerformanceObserver(list =>for (const entry of list.getEntries()){
            report({ name, data: entry });
        }
        p.observe({ entryTypes });
    }
return {name, start}
}

JS 错误监控

利用 window.addEventListener 的 error 和 unhandledrejection 可以监控到全局的 js 错误。

静态资源错误监控

利用 window.addEventListener 的 error 事件可以监控到静态资源错误,注意要和 js error 进行区分。

请求异常监控

通过 hook xhr 和对象来监听 fetch 请求时发生的错误。

渐入佳境: 封装一个通用的 sdk

前端监控流程概述

前端监控流程:

  1. 数据采集
  2. 组装上报
  3. 清洗存储
  4. 数据消费

sdk 主要完成前两步,后两步需要后端服务和平台的支持,其中前面的章节已经完成了数据采集以及简单的数据组装。

临门一脚:数据上报

封装一个用于给监控器上报已收集数据的上报函数。

按需加载监控能力

课后探索:让你的 sdk 更健壮

更多性能指标计算算法

关注请求性能

请求异常除了请求错误外,还可以关注慢请求,可以参考 Performance Resource Timing 来获取请求各阶段耗时,找出所有慢请求。

更安全和稳定的 Hook 函数

在实现请求错误监控时,我们实现了一个很简易的 hook 函数,这个 hook 函数缺少了很关键的 unhook 能力,即将被 hook 的函数还原的能力,即还需要补全这一能力并写出更安全和稳定的 hook 函数。

用户行为监控

数据存储与消费