前端错误监控实战:window.onerror + PerformanceObserver 做轻量上报
为什么需要前端错误监控
线上问题最怕“用户遇到了,开发不知道”。报错只存在于用户浏览器的控制台里,等客服反馈时,往往已经影响了一批人。前端错误监控就是把这些错误采集回来,变成可统计、可定位的指标。对中小项目来说,不必一上来就接重型 APM,用浏览器原生 API 就能搭一套轻量上报方案。
window.onerror:兜底的错误网
window.onerror 是最基础的全局错误捕获入口,脚本里的语法错误、运行时异常都会走到这里。注册时返回 true 可以阻止错误继续在控制台刷屏,按需使用即可:
window.onerror = function (message, source, lineno, colno, error) {
report({
type: 'js-error',
message: message,
source: source,
lineno: lineno,
colno: colno,
stack: error && error.stack
});
return true;
};
只用 onerror 还不够。Promise 里的异常不会触发它,需要再监听 unhandledrejection;图片、脚本加载失败也不会冒泡到 window.onerror,要在捕获阶段监听 error 事件:
window.addEventListener('unhandledrejection', function (e) {
report({ type: 'promise-error', message: String(e.reason) });
});
window.addEventListener('error', function (e) {
if (e.target && e.target !== window) {
report({
type: 'resource-error',
tag: e.target.tagName,
src: e.target.src || e.target.href
});
}
}, true);
PerformanceObserver:看得见的性能
错误之外,性能劣化同样值得监控。PerformanceObserver 可以订阅浏览器的性能条目,拿到关键指标:
var observer = new PerformanceObserver(function (list) {
var entries = list.getEntries();
for (var i = 0; i < entries.length; i++) {
var entry = entries[i];
if (entry.entryType === 'largest-contentful-paint') {
report({ type: 'lcp', value: entry.startTime });
}
if (entry.entryType === 'longtask') {
report({ type: 'longtask', duration: entry.duration });
}
}
});
observer.observe({ entryTypes: ['largest-contentful-paint', 'longtask', 'resource'] });
LCP 反映首屏体验,长任务往往与页面卡顿、点击无响应直接相关。resource 条目还能顺带统计慢接口和失败资源,与错误数据相互印证,定位问题更快。
上报:轻量也有讲究
采集到数据后,上报环节要注意三点。一是采样,错误高频爆发时先在端上聚合、节流,避免把监控本身变成对服务端的压力;二是用 navigator.sendBeacon 或 fetch 的 keepalive,保证页面关闭时数据也能发出;三是脱敏,错误信息和 URL 里可能带有 token,要先清洗再上传。
收尾:先跑起来,再谈完善
轻量方案的价值在于“先有数据”:全局错误、未处理的 Promise 异常、资源加载失败、LCP 与长任务,这五类数据落地后,大部分线上问题都能做到“看得见、找得到”。后续再按需补充分桶统计、告警阈值和 Sourcemap 堆栈还原,就能从“能用”进化到“好用”。
- 点赞
- 收藏
- 关注作者
评论(0)