核心是利用Long Tasks API捕获主线程阻塞≥50ms任务,通过sendBeacon异步上报;需早期注册监听、过滤聚合(如≥100ms、去重)、补充导航/路由等上下文,并结合Event Timing、Navigation Timing等交叉验证,辅以采样与debug开关。

监控长任务并上报性能日志,核心是利用 Long Tasks API 捕获主线程阻塞超过 50ms 的任务,并通过可靠方式(如 sendBeacon)异步上报。
监听长任务:使用 Long Tasks API
浏览器原生提供 PerformanceObserver 监听 "longtask" 类型条目,每个条目包含任务开始时间、持续时间、来源上下文等关键信息:
- 需在页面早期(如
<head>中或DOMContentLoaded前)注册,避免漏掉首屏长任务 - 每个
entry的duration是实际阻塞时长(单位毫秒),startTime是相对于performance.timeOrigin的时间戳 - 注意兼容性:Chrome 68+、Edge 79+、Firefox 75+ 支持;Safari 尚未支持,需降级处理(如用
requestIdleCallback+ 时间切片粗略估算)
过滤与聚合:减少日志噪音
直接上报所有长任务易造成日志爆炸,建议按场景做轻量处理:
- 只上报
duration >= 100ms的任务(比默认阈值更严格,聚焦明显卡顿) - 对同一页面内高频出现的同类长任务(如反复触发的某个 React commit 阶段)做简单去重或计数聚合,避免重复上报
- 补充上下文:加入
navigationType(reload/forward/back)、isFirstPaint状态、当前路由 path,便于归因
可靠上报:优先用 sendBeacon
长任务常发生在用户即将离开页面(如跳转、关闭)时,必须确保日志不丢失:
立即学习“Java免费学习笔记(深入)”;
- 用
navigator.sendBeacon(url, data)发送,该方法异步且在页面卸载时仍能发出请求 -
data建议用JSON.stringify后的字符串,Content-Type 设为text/plain(sendBeacon不支持自动设置application/json) - 若
sendBeacon不可用(如旧浏览器),回退到Image打点(URL 参数形式)或fetch(..., { keepalive: true })
结合其他指标交叉验证
单看长任务不够全面,建议关联以下数据提升分析价值:
- 与
Event Timing API(如click、input的processingEnd)比对,确认交互是否被阻塞 - 叠加
Navigation Timing数据(如domComplete - domInteractive),判断长任务是否集中在首屏渲染后期 - 记录 JS 内存使用峰值(
performance.memory,仅 Chrome)辅助排查内存压力导致的 GC 长停顿
不复杂但容易忽略:别忘了在上报前做采样(如 10% 用户),避免日志服务过载;同时保留本地 debug 开关,方便 QA 或灰度阶段临时开启全量采集。



















