tech share
  • tech-share
  • Engineering
    • 登录鉴权
    • SSR 页面路由
    • npm 版本号
    • 缓存
    • 数据库容灾
    • 动态效果导出 gif
    • Chrome-devtools
    • C 端 H5 性能优化
    • Docker
    • Monorepo 最佳实践
    • 技术架构演化
    • 项目规范最佳实践
    • snowpack
    • 静态资源重试
    • 前端页面渲染分析
    • Git
    • 前端重构
    • 微前端
    • 项目依赖分析
    • 前端监控原理
    • webpack
    • BS 架构与 CS 架构
    • HTTPS
    • package-lock.json 生成逻辑
    • SVN(Subversion)
    • 数据库分类
    • gulp
    • 前端架构
    • Bundle & Bundless
    • 控制反转 IoC
  • JavaScript
    • Javascript 性能
    • JavaScript 原型(2) - 原型与原型链
    • JavaScript 原型(1) - 构造函数
    • JavaScript - Promise
    • ES6 解构赋值
    • 前端离线化
    • Proxy
    • Object.defineProperty()简介
    • TypeScript
  • MachineLearning
    • GAN生成对抗网络
    • 虚拟对抗训练
    • 深度度量学习
    • 原型网络
    • PyTorch优化器
    • 隐马尔可夫模型2
    • Shapley Value 算法
    • Embarassingly Autoencoder算法
    • AutoRec算法及其后续发展
    • 深度学习常用激活函数
    • 序列预测ConvTran算法
    • 联邦学习
    • 深度学习推荐系统算法整理
    • 隐马尔可夫模型
    • 黎曼优化方法
    • FM算法
    • 机器学习常见评价指标
    • VAE算法
    • Adam优化器详解
    • Transformer算法
    • Self-attention 推荐算法
    • CNN 卷积神经网络
    • 图嵌入
    • 集成学习算法
    • RecBole开源框架
    • NCE-PLRec
    • 深度学习初始化方法
    • RNN循环神经网络
    • PyTorch数据处理
    • PyTorch安装和基本操作
    • XGBoost算法
    • NCF算法与简单MF的对比
    • 计算最佳传输
  • CSS
    • 什么是BFC
    • 纯CSS实现可拖动布局
    • 滚动穿透解决方案
  • React
    • React 生命周期
    • React Ref
    • React Hooks
    • SWR
    • React 数据流
    • React 函数式组件和类组件的区别
  • 可视化
    • OffscreenCanvas
    • Echarts 平滑曲线端点为什么不平滑
    • 颜色空间
    • 词云布局解析
    • 3D 数学基础
    • Canvas 图片处理
    • GLGL ES
    • WebGL 中绘制直线
    • Graphics API
    • 现代计算机图形学基础
    • Canvas 灰度
  • Vue
    • Vue2.x全局挂载整理
    • Vue2.6.x源码阅读
      • Vue2.6.x源码阅读 - 2.目录结构分析
      • Vue2.6.x源码阅读 - 4.源码阅读-platform
      • Vue2.6.x源码阅读 - 1.准备工作
      • Vue2.6.x源码阅读 - 5.源码阅读-core-Vue构造函数
      • Vue2.6.x源码阅读 - 7.源码阅读-core-响应式原理
      • Vue2.6.x源码阅读 - 3.源码阅读-shared
      • Vue2.6.x源码阅读 - 6.源码阅读-core-组件挂载
    • Vue + TypeScript Web应用实践
    • Vue2.x指令
    • nextTick()的使用
    • vue-cli2.x 的使用与项目结构分析
    • Vue响应式原理及总结
    • VueX的使用
    • Electron-Vue + Python 桌面应用实践
    • Vite
    • Vue组件通信整理
    • 记录一个问题的探索过程
  • Linux
    • memcg
  • GameDev
    • 游戏中的几种投影视图
    • 从零开始写软渲染器06
    • 从零开始写软渲染器05
    • 从零开始写软渲染器04
    • 从零开始写软渲染器03
    • 从零开始写软渲染器02
    • 从零开始写软渲染器01
    • 从零开始写软渲染器00
    • 现代游戏常用的几种寻路方案(一)
  • Node
    • NPM Dependency
    • Node 优势
    • Node Stream
    • Node 模块系统
  • HTML
    • html5语义与结构元素
  • 跨端
    • Flutter 介绍
  • Golang
    • Golang 基础
  • AR
    • SceneKit
由 GitBook 提供支持
在本页
  • 监控上报策略
  • 页面关闭时
  • 批量上报收益
  • 代码混淆与 sourseMap
  • 性能指标
  • 异常监控
  • 监控 Web 页面的 HTTP 请求异常
  • 监控崩溃
  • 客户端 JS 主线程
  • Web Worker
  • 监控卡顿

这有帮助吗?

  1. Engineering

前端监控原理

上一页项目依赖分析下一页webpack

最后更新于4年前

这有帮助吗?

监控上报策略

如果监控的上报策略是即时上报、一次上报一条,这种情况会导致上报请求过多。为了减少服务端压力、减少部分客户端对上报量的限制(小程序每秒只能上报 5 个请求),监控请求需聚合上报。 分为以下几种:

  • BatchIndexes:批量上报索引(包含性能等其他日志),可一次批量上报 N 条(最常使用的上报方法)

  • MomentIndexes:即时上报索引,一次全部上报

  • FeedbackIndexes:用户反馈索引,一次上报一条

页面关闭时

生命周期监测: beforeunload, unload, pagehide, and visibilitychange 由于页面关闭的时候将,将采用。 当用户关闭网页的时候,需要上报一些数据。很自然的做法是在 unload 事件或 beforeunload 事件的监听函数里面,使用 XMLHttpRequest 对象发送数据。但是,这样做不是很可靠,因为 XMLHttpRequest 对象是异步发送,很可能在它即将发送的时候,页面已经卸载了,从而导致发送取消或者发送失败。 解决方法就是 AJAX 通信改成同步发送,即只有发送完成,页面才能卸载。将请求改为同步以后,会阻塞页面关闭或重新加载的过程,这样就会影响用户体验。而且很多浏览器已经不支持同步的 XMLHttpRequest 对象了(即 open()方法的第三个参数为 false)。 为了解决上述问题,便有了 sendBeacon 方法,使用该方法发送请求,可以保证数据有效送达,且不会阻塞页面的卸载或加载,并且编码比起上述方法更加简单。

批量上报收益

  • 减少用户网络请求个数,小程序限制网络请求数,必须改为聚合上报

  • 减少服务端带宽成本和入口层吞吐。

代码混淆与 sourseMap

Source Map,顾名思义,是保存源代码映射关系的文件,使用 webpack 的开发者对它应该不会陌生。在项目开发完进行打包后,在打包的文件夹里通常除了 js,css,图片字体等资源文件外,还会有 xxx.js.map 的文件。这种带 map 后缀的文件就是 Source Map 文件——它保存了源代码和转换之后代码(通常经过压缩混淆和其他转换)的关系。 我们的代码在经过以下过程后往往会变得“面目全非”

  • 压缩混淆(UglifyJS)//压缩打包

  • 编译(TypeScript)//TS->JS

  • 转译(Babel)//ES6->ES5

  • 合并多个文件,减少带宽请求。//减少资源包大小

sourceMap 的格式

{
  version : 3, //SourceMap 的版本,目前为 3
  sources: ["foo.js", "bar.js"], //转换前的文件,该项是一个数组,表示可能存在多个文件合并
  names: ["src", "maps", "are", "fun"], //转换前的所有变量名和属性名
  mappings: "AACvB,gBAAgB,EAAE;AAClB;", //记录位置信息的字符串
  file: "out.js", //转换后的文件名
  sourcesContent: " \t// The module cache\n", //转换后的代码
  sourceRoot : "" //转换前的文件所在的目录。如果与转换前的文件在同一目录,该项为空
}

推荐两篇关于 sourceMap mappings 的文章,非常详细且好理解:

性能指标

  • FP (First Paint) 为首次渲染的时间点,在性能统计指标中,从用户开始访问 Web 页面的时间点到 FP 的时间点这段时间可以被视为 白屏时间 (通过 PerformancePaintTiming API 获取)

  • FCP (First Contentful Paint) 为首次有内容渲染的时间点,在性能统计指标中,从用户开始访问 Web 页面的时间点到 FCP 的时间点这段时间可以被视为 无内容时间 (通过 PerformancePaintTiming API 获取)

  • FMP(First Meaningful Paint) 即首次绘制有意义内容的时间,前端业界现在比较认可的一个计算 FMP 的方式就是「认定页面在加载和渲染过程中最大布局变动之后的那个绘制时间即为当前页面的 FMP 」(通过 MutationObserver API 获取)

  • TTI(Time To Interactive) 即从页面加载开始到页面处于完全可交互状态所花费的时间。 【RUM】如何计算 Web 页面的 TTI 指标 (通过算法获取)

异常监控

监控 Web 页面的 JS 运行时异常 JS 运行时异常通常分为以下几种类型:

  • EvalError

  • InternalError

  • RangeError

  • ReferenceError

  • SyntaxError

  • TypeError

  • URIError

window.onerror = function (message, source, lineno, colno, error) {
  // Sentry 异常上报数据格式
};

监控 Web 页面的 HTTP 请求异常

HTTP 请求异常定义 HTTP 请求异常指的是 HTTP 请求失败或者 HTTP 请求返回的状态码非 20X,主要指的是 AJAX 或者 Fetch API 的 HTTP 请求。需要对原生的 XMLHttpRequest 对象和 fetch 方法进行重写,从而在代理对象或方法中实现状态码的监听和错误的上报。

监控崩溃

崩溃监控其实应该叫做【卡死监控】,其实现机制是通过 worker 线程每 2 秒向主线程发送一个心跳包来判断主线程是否卡死,超过 6s 没有心跳则认为已经 crash。

客户端 JS 主线程

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

Web Worker

定期(2s)检查是否收到心跳。 超过一定时间(6s)未收到心跳,则认为页面崩溃。 检测到崩溃后,通过 HTTP 请求进行异常上报。

监控卡顿

实现原理:

持续每隔 1s 记录一次页面的 FPS 数值 每次记录 FPS 时候进行判断,如果连续 N 次页面的 FPS 数值小于 M,则认为页面发生了卡顿 目前卡顿监控是通过每隔一秒计算页面 FPS(屏幕每秒渲染的帧数),当页面 FPS 低于一定阈值时则上报为一次卡顿。Web 页面的卡顿一般在很多情况下往往是由于用户操作带来的,例如 click 或者 keydown。所以我们可以在事件捕获阶段,开始监控 FPS 的变化,从而判断是否引起了一次用户感知的到的卡顿。具体方式可以描述为:用户交互后渲染新的一帧需要的时间大于阈值 T 表示一次卡顿。 由于 FPS 的计算是通过 RAF(requestAnimationFrame)获取,加上每秒一次的定时计算,对一些比较重视性能的场景(如端内)消耗过大,且目前由于未知因素导致的卡顿误报率较高。

可采用 对 JS 运行时异常进行上报的。 当 JavaScript 运行时错误 发生时,window 会触发一个 ErrorEvent 接口的 error 事件,并执行 window.onerror 回调函数。因此可以在 window.onerror 的回调函数中获取 JS 异常。

禁止发出 XHR 请求
sendBeacon
https://juejin.cn/post/6844903869928079373
http://www.qiutianaimeili.com/html/page/2019/05/89jrubx1soc.html
Sentry