onerror死循环会导致浏览器卡顿、内存持续上涨、devtools偶尔崩溃且控制台不报错;需通过img打标+限频+beacon上报检测告警,fallback图须用base64防二次循环。

onerror死循环会导致什么现象
浏览器卡顿、内存持续上涨、DevTools 偶尔崩溃,但控制台往往不报错——因为这不是 JS 异常,而是事件不断重入导致的资源耗尽。真实项目中,这种问题常在灰度发布后才暴露:某张 fallback 图路径写错(比如拼成 fallback.pngn),所有用该模板渲染的头像/图标全部触发无限 onerror,用户侧表现为页面响应变慢、滚动卡顿,监控却看不到 JS 错误。
如何检测并告警 onerror 循环
不能依赖 try/catch(onerror 是事件,不是抛异常),也不能只监听 window.onerror(它捕获不到 img.onerror 自身的重复触发)。核心思路是:给每个 img 打标 + 限频 + 上报。
- 在内联
onerror中加计数器和时间戳:onerror="if (!this.dataset.errcnt) this.dataset.errcnt = '1'; else { this.dataset.errcnt = (+this.dataset.errcnt + 1) + ''; if (+this.dataset.errcnt > 3) { reportImgLoop(this); } }; this.src='fallback.png'; this.onerror=null;" -
reportImgLoop()发送轻量 Beacon 请求,带上this.src、this.dataset.errcnt、document.URL和performance.now()时间戳 - 服务端聚合:同一
src在 1 分钟内触发 >10 次循环,立即触发企业微信/钉钉告警
为什么不能只靠前端 console.warn
生产环境通常关闭 console 输出,且 warn 不可监控;更重要的是,循环可能在用户切到其他 tab 后仍在后台运行(尤其 Safari),此时页面不可见,warn 完全丢失。Beacon 是唯一可靠方案——它异步、不阻塞、即使页面卸载也会尽力发出。
另外注意:reportImgLoop 内部必须用 navigator.sendBeacon,不能用 fetch 或 XMLHttpRequest,否则页面跳转时请求大概率被丢弃。
容易被忽略的埋点细节
fallback 图本身也得有降级,否则 reportImgLoop 里再加载一张图,又可能触发新循环。建议 fallback 统一用 base64 占位:data:image/svg+xml;base64,PHN2Zy...。同时,上报字段里必须包含原始 src 的域名和路径层级(如 cdn.example.com/icons/),方便快速定位是 CDN 配置错误,还是构建产物漏文件。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











