深入浅出前端监控

发表于 2年以前  | 总阅读数:379 次

背景

近期主要工作内容是进校开放平台(简称开平)相关业务,开平简单来说就是一个可为第三方应用提供接入主端(例如微信、飞书)应用能力的平台,为了让第三方应用稳定可靠地接入开平,需要为其提供一些底层的基础能力,其中应用监控就是其中不可或缺的一环。目前如何在进校开平中做三方应用的监控管理还在初步预研阶段,为此了解了一下前端监控相关背景知识。鉴于我司已有一套非常完善的 APM 平台,因此下文诸多理论和源码参考自我司 APM Web SDK 源码,之后以 APM 代称。

监控流程

  1. 数据采集:明确需要采集哪些指标以及采集的方式。
  2. 数据上报:将上一步采集的数据以一定的策略进行上报。
  3. 数据清洗、存储:服务端在接收到上报数据后需要对数据进行清洗和存储。
  4. 数据消费:数据最终会在类似 APM 这样的监控平台以图、表等形式分类别地进行可视化展示,并提供诸如监控报警等消费能力。

上述流程看似不复杂但每个环节的技术细节都非常多,本文主要关注前端视角下的数据采集和上报环节。

数据采集

做好前端监控的第一步要明确哪些数据是值得我们采集的,前端环境下监控数据从大的维度上可划分成环境信息、异常数据和性能数据:

环境信息

采集的监控数据一般都会设置一些通用的环境信息,这些环境信息可以提供更多的维度以帮助用户发现问题和解决问题。下图列举了一些常见的环境信息:

异常监控

JS 异常

Script Error

先抛开如何采集 JS 异常信息不谈,在采集之前如果连报错信息都不全那么即使采集到了这样的数据也是无效的。巧的是,确实存在这样一个场景:当页面加载自不同域的脚本(例如页面的 JS 托管在 CDN)中发生语法错误时,浏览器基于安全机制考虑,不会给出语法错误的细节,而是简单的 Script error.

因此,如果你希望自己页面的详细报错信息被监控 SDK 捕获你需要为页面中的脚本 script 添加 crossorigin= anonymous属性,且脚本所在的服务设置 CORS 响应头 Access-Control-Allow-Origin: *,这是 JS 异常监控的第一项准备工作。

编译时与运行时错误

常见的 JS 错误可分为编译时错误和运行时错误,其中编译时错误在 IDE 层面就会给出提示,一般不会流入到线上,因此编译时错误不在监控范围。

有的同学说在 APM 上时常看到 SyntaxError 的字样,这种情况一般都是 JSON.parse 解析出错或浏览器兼容性问题导致,属于运行时错误并非编译时错误。

对于异常监控我们主要关注 JS 运行时错误,多数场景下的处理手段如下:

错误场景 如何上报
场景一:自行感知的同步运行时异常 try-catch 后进行错误上报
场景二:没有手动 catch 的运行时异常(包括异步但不包括 promise 异常 ) 通过 window.onerror进行监听
场景三:自行感知的 promise 异常 promise catch 进行捕获后进行错误上报
场景四:没有手动 catch 的 promise 异常 监听 window 对象的 unhandledrejection 事件

整体来看,监控 SDK 会在全局帮助用户去捕获他们没有自行感知的异常并上报,对于自行捕获的异常一般会提供手动上报接口进行上报。

SourceMap

假设现在已经采集到页面目前存在的 JS 异常并做了上报,最终消费时你我们当然希望看到的是错误的初始来源和调用堆栈,但实际发生报错的 JS 代码都经过各种转换混淆压缩,早已面目全非了,因此这里需要借助打包阶段生成的 SourceMap 做一个反向解析得到原始报错信息的上下文。

以 Sentry (APM 也有用到 Sentry)为例大致流程如下:

1 . 采集侧收集错误信息发送到监控平台服务端。

2 . 接入的业务方自行上传 SourceMap 文件到监控平台服务端,上传完成后删除本地的 SourceMap文件,且打包后的 js 文件末尾不需要 SourceMap URL,最大程度避免 SourceMap 泄漏。

3 . 服务端通过 source-map 工具结合 SourceMap 和原始错误信息定位到源码具体位置。

静态资源加载异常

静态资源加载异常的捕获存在两种方式:

1 . 在出现静态资源加载异常的元素的 onerror 方法中处理。

2 . 资源加载异常触发的error事件不会冒泡,因此使window.addEventListener('error', cb,true) 在事件捕获阶段进行捕获。

第一种方式侵入性太强,不够优雅,目前主流方案均采用第二种方式进行监控:

捕获静态资源加载异常

APM 平台一般会有所有静态资源加载的明细,其原理是通过 PerformanceResourceTiming API 来采集静态资源加载的基本情况,这里不做展开。

请求异常

业务中的 AJAX 请求或者 Fetch 请求在不同的网络环境或者客户端环境会有不稳定的表现,这些不稳定的情况我们很难通过本地测试的途径进行测试或者感知得到,所以我们需要对 HTTP 请求进行线上监控,通过将 HTTP 请求异常上报的方式对错误日志进行采集,然后进行一系列的分析和监控。

请求异常通常泛指 HTTP 请求失败或者 HTTP 请求返回的状态码非 20X。

那么请求异常监控怎么做呢?普遍采用的方式是对原生的 XMLHttpRequest 对象和 fetch 方法进行重写,从而在代理对象中实现状态码的监听和错误上报:

重写 XMLHttpRequest 对象

重写 fetch 方法

当然了,重写上述方法后除了异常请求可以被监控到之外,正常响应的请求状态自然也能被采集到,比如 APM 会将对所有上报请求的持续时间进行分析从而得出慢请求的占比:

PS:如果通过 XHR 或 fetch 来上报监控数据的话,上报请求也会被被拦截,可以有选择地做一层过滤处理。

卡顿异常

卡顿指的是显示器刷新时下一帧的画面还没有准备好,导致连续多次展示同样的画面,从而让用户感觉到页面不流畅,也就是所谓的掉帧,衡量一个页面是否卡顿的指标就是我们熟知的 FPS。

如何获取 FPS

Chrome DevTool 中有一栏 Rendering 中包含 FPS 指标,但目前浏览器标准中暂时没有提供相应 API ,只能手动实现。这里需要借助 requestAnimationFrame 方法模拟实现,浏览器会在下一次重绘之前执行 rAF 的回调,因此可以通过计算每秒内 rAF 的执行次数来计算当前页面的 FPS

通过 rAF 计算 FPS

如何上报“真实卡顿”

从技术角度看 FPS 低于 60 即视为卡顿,但在真实环境中用户很多行为都可能造成 FPS 的波动,并不能无脑地把 FPS 低于 60 以下的 case 全部上报,会造成非常多无效数据,因此需要结合实际的用户体验重新定义“真正的卡顿”,这里贴一下司内 APM 平台的上报策略

1 . 页面 FPS 持续低于预期:当前页面连续 3s FPS 低于 20。

2 . 用户操作带来的卡顿:当用户进行交互行为后,渲染新的一帧的时间超过 16ms + 100ms。

崩溃异常

Web 页面崩溃指在网页运行过程页面完全无响应的现象,通常有两种情况会造成页面崩溃:

1 . JS 主线程出现无限循环,触发浏览器的保护策略,结束当前页面的进程。

2 . 内存不足

发生崩溃时主线程被阻塞,因此对崩溃的监控只能在独立于 JS 主线程的 Worker 线程中进行,我们可以采用 Web Worker 心跳检测的方式来对主线程进行不断的探测,如果主线程崩溃,就不会有任何响应,那就可以在 Worker 线程中进行崩溃异常的上报。这里继续贴一下 APM 的检测策略:

  • JS 主线程:

  • 固定时间间隔(2s)向 Web Worker 发送心跳

  • Web Worker:

  • 定期(2s)检查是否收到心跳。

  • 超过一定时间(6s)未收到心跳,则认为页面崩溃。

  • 检测到崩溃后,通过 http 请求进行异常上报。

崩溃检测

性能监控

性能监控并不只是简单的监控“页面速度有多快”,需要从用户体验的角度全面衡量性能指标。(就是所谓的 RUM 指标)目前业界主流标准是 Google 最新定义的 Core Web Vitals:

  • 加载(loading)LCP
  • 交互(interactivity)FID
  • 视觉稳定(visual stability)CLS

可以看到最新标准中,以往熟知的 FP、FCP、FMP、TTI 等指标都被移除了,个人认为这些指标还是具备一定的参考价值,因此下文还是会将这些指标进行相关介绍。(谷歌的话不听不听)

Loading 加载

和 Loading 相关的指标有 FPFCPFMPLCP,首先来看一下我们相对熟悉的几个指标:

FP/FCP/FMP

一张流传已久的图

  • FP (First Paint): 当前页面首次渲染的时间点,通常将开始访问 Web 页面的时间点到 FP 的时间点的这段时间视为白屏时间,简单来说就是有屏幕中像素点开始渲染的时刻即为 FP。
  • FCP ( First Contentful Paint ): 当前页面首次有内容渲染的时间点,这里的 内容 通常指的是文本、图片、svg 或 canvas 元素。

这两个指标都通过 PerformancePaintTiming API 获取:

通过 PerformancePaintTiming 获取 FP 和 FCP

下面再来看 FMP 的定义和获取方式:

  • FMP (First Meaningful Paint): 表示首次绘制有意义内容的时间,在这个时刻,页面整体布局和文字内容全部渲染完成,用户能够看到页面主要内容,产品通常也会关注该指标。

FMP 的计算相对复杂,因为浏览器并未提供相应的 API,在此之前我们先看一组图:

从图中可以发现页面渲染过程中的一些规律:

1 . 在 1.577 秒,页面渲染了一个搜索框,此时已经有 60 个布局对象被添加到了布局树中。

2 . 在 1.760 秒,页面头部整体渲染完成,此时布局对象总数是 103 个。

3 . 在 1.907 秒,页面主体内容已经绘制完成,此时有 261 个布局对象被添加到布局树中从用户体验的角度看,此时的时间点就是是 FMP。

可以看到布局对象的数量与页面完成度高度相关。业界目前比较认可的一个计算 FMP 的方式就是——「页面在加载和渲染过程中最大布局变动之后的那个绘制时间即为当前页面的 FMP 」

实现原理则需要通过 MutationObserver 监听 document 整体的 DOM 变化,在回调计算出当前 DOM 树的分数,分数变化最剧烈的时刻,即为 FMP 的时间点

至于如何计算当前页面 DOM 的分数,LightHouse 的源码中会根据当前节点深度作为变量做一个权重的计算,具体实现可以参考 LightHouse 源码。

const curNodeScore = 1 + 0.5 * depth;
const domScore = 所有子节点分数求和

上述计算方式性能开销大且未必准确,LightHouse 6.0 已明确废弃了 FMP 打分项,建议在具体业务场景中根据实际情况手动埋点来确定 FMP 具体的值,更准确也更高效。

LCP

没错,LCP (Largest Contentful Paint) 是就是用来代替 FMP 的一个性能指标 ,用于度量视口中最大的内容元素何时可见,可以用来确定页面的主要内容何时在屏幕上完成渲染。

使用 Largest Contentful Paint API 和 PerformanceObserver 即可获取 LCP 指标的值:

获取 LCP

Interactivity 交互

TTI

TTI(Time To Interactive) 表示从页面加载开始到页面处于完全可交互状态所花费的时间, TTI 值越小,代表用户可以更早地操作页面,用户体验就更好。

这里定义一下什么是完全可交互状态的页面

1 . 页面已经显示有用内容。

2 . 页面上的可见元素关联的事件响应函数已经完成注册。

3 . 事件响应函数可以在事件发生后的 50ms 内开始执行(主线程无 Long Task)。

TTI 的算法略有些复杂,结合下图看一下具体步骤:

TTI 示意图

Long Task: 阻塞主线程达 50 毫秒或以上的任务。

1 . 从 FCP 时间开始,向前搜索一个不小于 5s 的静默窗口期。(静默窗口期定义:窗口所对应的时间内没有 Long Task,且进行中的网络请求数不超过 2 个)

2 . 找到静默窗口期后,从静默窗口期向后搜索到最近的一个 Long Task,Long Task 的结束时间即为 TTI。

3 . 如果一直找到 FCP 时刻仍然没有找到 Long Task,以 FCP 时间作为 TTI。

其实现需要支持 Long Tasks API 和 Resource Timing API,具体实现感兴趣的同学可以按照上述流程尝试手动实现。

FID

FID(First Input Delay) 用于度量用户第一次与页面交互的延迟时间,是用户第一次与页面交互到浏览器真正能够开始处理事件处理程序以响应该交互的时间。

其实现使用简洁的 PerformanceEventTiming API 即可,回调的触发时机是用户首次与页面发生交互并得到浏览器响应(点击链接、输入文字等)。

获取 FID

至于为何新的标准中采用 FID 而非 TTI,可能存在以下几个因素:

  • FID 是需要用户实际参与页面交互的,只有用户进行了交互动作才会上报 FID,TTI 不需要。
  • FID 反映用户对页面交互性和响应性的第一印象,良好的第一印象有助于用户建立对整个应用的良好印象。

Visual Stability 视觉稳定

CLS

CLS(Cumulative Layout Shift) 是对在页面的整个生命周期中发生的每一次意外布局变化的最大布局变化得分的度量,布局变化得分越小证明你的页面越稳定

听起来有点复杂,这里做一个简单的解释:

  • 不稳定元素:一个非用户操作但发生较大偏移的可见元素称为不稳定元素。
  • 布局变化得分:元素从原始位置偏移到当前位置影响的页面比例 * 元素偏移距离比例

举个例子,一个占据页面高度 50% 的元素,向下偏移了 25%,那么其得分为 0.75 * 0.25,大于标准定义的 0.1 分,该页面就视为视觉上没那么稳定的页面。

使用 Layout Instability API 和 PerformanceObserver 来获取 CLS:

获取 CLS

一点感受:在翻阅诸多参考资料后,私以为性能监控是一件长期实践、以实际业务为导向的事情,业内主流标准日新月异,到底监控什么指标是最贴合用户体验的我们不得而知,对于 FMP、FPS 这类浏览器未提供 API 获取方式的指标花费大量力气去探索实现是否有足够的收益也存在一定的疑问,但毋容置疑的是从自身页面的业务属性出发,结合一些用户反馈再进行相关手段的优化可能是更好的选择。(更推荐深入了解浏览器渲染原理,写出性能极佳的页面,让 APM 同学失业

数据上报

得到所有错误、性能、用户行为以及相应的环境信息后就要考虑如何进行数据上报,理论上正常使用ajax 即可,但有一些数据上报可能出现在页面关闭 (unload) 的时刻,这些请求会被浏览器的策略 cancel 掉,因此出现了以下几种解决方案:

1 . 优先使用 Navigator.sendBeacon,这个 API 就是为了解决上述问题而诞生,它通过 HTTP POST 将数据异步传输到服务器且不会影响页面卸载。

2 . 如果不支持上述 API,动态创建一个 <img / > 标签将数据通过 url 拼接的方式传递。

3 . 使用同步 XHR 进行上报以延迟页面卸载,不过现在很多浏览器禁止了该行为。

APM 采取了第一种方式,不支持 sendBeacon 则使用 XHR,偶尔丢日志的原因找到了。

由于监控数据通常量级都十分庞大,因此不能简单地采集一个就上报一个,需要一些优化手段:

  • 请求聚合:将多条数据聚合一次性上报可以减少请求数量,例如我们打开任意一个已接入 APM 的页面查看 batch 请求的请求体:

  • 设置采样率: 像崩溃、异常这类数据不出意外都是设置 100% 的采样率,对于自定义日志可以设置一个采样率来减少请求数量,大致实现思路如下:

总结

本文旨在提供一个相对体系的前端监控视图,帮助各位了解前端监控领域我们能做什么、需要做什么。此外,如果能对页面性能和异常处理有着更深入的认知,无论是在开发应用时的自我管理(减少 bug、有意识地书写高性能代码),还是自研监控 SDK 都有所裨益。

如何设计监控 SDK 不是本文的重点,部分监控指标的定义和实现细节也可能存在其他解法,实现一个完善且健壮的前端监控 SDK 还有很多技术细节,例如每个指标可以提供哪些配置项、如何设计上报的维度、如何做好兼容性等等,这些都需要在真实的业务场景中不断打磨和优化才能趋于成熟。

参考

Google Developer

本文由哈喽比特于2年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/9L3ck2DGbSapWatte5i9Mw

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:1年以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:1年以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:1年以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:1年以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:1年以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:1年以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:1年以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:1年以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:1年以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:1年以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:1年以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:1年以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:1年以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:1年以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:1年以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:1年以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:1年以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:1年以前  |  398次阅读  |  详细内容 »
 相关文章
Android插件化方案 5年以前  |  237227次阅读
vscode超好用的代码书签插件Bookmarks 2年以前  |  8063次阅读
 目录