前端监控 SDK 开发 | 青训营笔记

80 阅读7分钟

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

一、本堂课重点内容:

前端监控的内容

  • 前端监控的定义
  • 需要前端监控的理由
  • 前端监控的功能

前端监控之常用性能指标

  • web性能标准的诞生
  • 传统的性能指标
  • 以用户为中心的性能指标

前端监控之前端常见异常

  • 静态资源错误
  • 请求异常
  • Js 错误
  • 白屏异常

监控前端性能与异常

  • 性能指标监控
  • Js 错误监控
  • 静态资源错误监控
  • 请求异常监控

封装一个通用的sdk

  • 前端监控流程
  • 概述临门一脚:数据上报
  • 按需加载监控能力

二、详细知识点介绍:

1.前端监控的内容

1.1 前端监控的定义

image.png

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

1.2 需要前端监控的理由

用户角度的可能问题:网页卡慢、图片缺损缺失

当我们的网页有了前端监控的能力时:

  • 打开好慢——页面某个关键资源渲染太慢。
  • 交互卡顿—页面同步计算任务太重,阻塞渲染。
  • 资源加载失败———客户端网络状态差,或上游服务节点异常。
  • 页面白屏——页面脚本执行失败、关键资源加载失败、请求失败等。

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

前端监控重要的原因:

  1. 缤趣(图片社交分享网站)将感知等待时间减少了40%,这将搜索引擎流量和注册星增加了15%。
  2. cooK C冷冻速食订购网站)将页面平均加载时间减少了850毫秒,从而将转化次数提高了7%,将跳出率降低了7%,并将每个会话的页面增加了10%.
  • 研究还表明,性能不佳会对业务目标产生负面影响。例如,BBC发现他们的网站加载时间每增加一秒,他们就会失去10%的用户。

1.3 前端监控的功能

监控了什么?

  1. 性能指标
  2. 异常事件
  3. 用户行为

2.前端监控之常用性能指标

2.1 web性能标准的诞生

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

2.2 传统的性能指标

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

image.png image.png image.png

2.3 以用户为中心的性能指标

[1]

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

这就是创建用户为中心的性能指标的原因,它们专注于用户视角下的浏览体验。

image.png

[2]

image.png
  • FP (First Paint):首次渲染的时间点。FP时间点之前,用户看到的都是没有任何内容的白色屏幕。
  • FCP(First Contentful Paint):首次有内容渲染的时间点。
  • FMP (First Meaningful Paint):首次绘制有意义内容的时间点。
image.png
  • TTI(Time to Interactive):测量页面从开始加载到主要子资源完成渲染,并能够快速、可靠地响应用户输入所需的时间。
  • TTI反映页面可用性的重要指标。TTI值越小,代表用户可以更早地操作页面,用户体验就更好。
image.png
  • sl(Speed Index):衡量页面可视区域加载速度,帮助检测页面的加载体验差异。
  • A和B的首次内容出现和完全加载时间是一样的,但是从用户角度A的体验明显更好。
  • FID (First Input Delay):测量从用户第一次与页面交互(比如当他们单击链接、点按按钮等等)直到浏览器对交互作出响应,实际能够开始处理事件时处理程序所经过的时间

3.前端监控之前端常见异常

3.1 静态资源错误

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

3.2 请求异常

Http请求状态码分类

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

请求异常=请求响应状态码>= 400

对于通过异步请求拉取的静态资源错误也可选择归纳到请求异常

3.3 Js 错误

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

image.png

3.4 白屏异常

前面几类异常都可以通过浏览器提供的标准化方法来监听到,而白屏异常没有标准化的监听方法,所以更考验前端监控开发者的功底。

通常我们可以通过判断DOM树的结构来粗略的判断白屏是否发生。

image.png

监听到白屏发生后,我们还需要对白屏的发生进行归因。

通常导致白屏发生的原因可能有如下几点:

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

4.监控前端性能与异常

4.1 性能指标监控

image.png image.png

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

image.png

4.2 Js 错误监控

image.png

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

4.3 静态资源错误监控

image.png

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

4.4 请求异常监控

image.png

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

5.封装一个通用的sdk

5.1 前端监控流程

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

image.png

5.2 概述临门一脚:数据上报

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

function createXhrMonitor(report: ({ name: string,data: any }) => void {
image.png

专为前端监控打造的请求函数Navigator.sendBeacon()

5.3 按需加载监控能力

function createSdk(url: string) {
const monitors: Array<{ name: string,start: Function }> = [];
const sdk = {
url,
report,
loadMonitor,
monitors,
start,
function report(f name: string, data: any }) {
//注意:数据发送前需要先序列化为字符串
    navigator.sendBeacon(url,JSON.stringify({ name: string,data: any })}
function loadMonitori{ name: string,start: Function }){
    monitors.push(i name: string, start: Function });
//实现链式调用
    return sdk;
    }
    function start() {
    monitors.forEach(m => m.start());
    }
    return sdk;
}
const sdk = createSdk ( "111.com");
const j sMonitor = createJsErrorMonitor( sdk.report);
sdk.loadMonitor(jsMonitor).loadMonitor(createPerfMonitor(sdk.report));
sdk.start();

三、实践练习例子:

Js错误监控

// 1.监听js执行报错
window.addEventListener("error", (e) => {
  //只有error属性不为空的ErrorEvent 才是一个合法的js 错误
  if (e.error) {
      console.log ('caputure an error', e.error);
      }
  });
//throw( new Error( 'test') );
//2.监听promise rejection
window.addEventListener("unhandledrejection", (e) => {console.log('capture a unrejection' , e);
});
Promise.reject('test');

四、课后个人总结:

通过本章学习,我了解清楚了前端监控的重要,以及前端监控的SDK开发,其中较难的可能就是开发环节;经过这个章节学习,对前端的开发调控有了进一步深入。