Skip to main content

前端错误监控

面试题:如何搭建一套前端错误监控?

完整的前端监控分三块:错误监控、性能监控、行为监控(埋点)。本篇聚焦错误监控,埋点见 埋点上报

错误捕获手段

错误类型捕获方式
JS 运行时错误window.onerror / window.addEventListener('error')
资源加载错误(img/script/css)window.addEventListener('error', cb, true)捕获阶段,资源错误不冒泡)
Promise 未捕获 rejectionwindow.addEventListener('unhandledrejection')
框架内错误Vue:app.config.errorHandler;React:ErrorBoundary + componentDidCatch
跨域脚本错误<script crossorigin> + 服务端 CORS 头,否则只报 Script error.
接口错误封装 fetch/axios 拦截器统一上报非 2xx
// JS 错误 + 资源错误(第三个参数 true 走捕获阶段)
window.addEventListener(
"error",
(event) => {
if (event.target && (event.target.src || event.target.href)) {
report({ type: "resource", url: event.target.src || event.target.href });
} else {
report({
type: "js",
message: event.message,
filename: event.filename,
line: event.lineno,
col: event.colno,
stack: event.error?.stack,
});
}
},
true
);

// Promise 错误
window.addEventListener("unhandledrejection", (event) => {
report({ type: "promise", reason: event.reason?.message || event.reason });
});

sourcemap 还原

面试题:上报的报错堆栈是压缩混淆后的,怎么定位源码?

生产代码经过压缩,堆栈里的行列号无意义。做法:构建时生成 .map 文件但不部署到线上(上传到监控平台),上报时带上压缩后的行列号,平台端用 source-map 库还原成源码位置。Sentry 就是这么做的。

上报要点

  • 上报通道:优先 navigator.sendBeacon(页面卸载也能发),降级用 new Image().src(无跨域预检)或 fetch(keepalive: true)
  • 去重与采样:相同错误聚合(按 message+stack 生成指纹),高频错误采样上报,避免打爆服务端。
  • 限流:单页面错误数设上限。
  • 附加上下文:用户 id、设备/浏览器、页面 url、用户操作录屏(如 rrweb)、面包屑(最近的几次操作)。

性能监控(关联)

PerformanceObserver + web-vitals 采集核心指标:

  • LCP(最大内容绘制)、INP(交互到下一次绘制,已取代 FID)、CLS(累积布局偏移)。
  • 首屏时间、白屏时间、资源加载耗时(performance.getEntriesByType('resource'))、接口耗时。
import { onLCP, onINP, onCLS } from "web-vitals";
onLCP(report);
onINP(report);
onCLS(report);

成熟方案:Sentry、阿里 ARMS、字节 Argos,自研可参考其架构。