PerformanceObserver 支持监听 longtask(Chrome/Edge/Opera 已实现,Firefox/Safari 未支持),用于捕获 ≥50ms 的主线程阻塞任务;element 类型尚无浏览器实现,属草案阶段,不可使用。

PerformanceObserver 可以监听长任务(longtask)和元素渲染(element)事件,但需注意:目前(截至 Chrome 125+)element 类型尚未被任何主流浏览器支持,属于草案阶段;而 longtask 已在 Chromium 系列(Chrome、Edge、Opera)中稳定支持,Firefox 和 Safari 尚未实现。
监听长任务(Long Tasks)
长任务指在主线程上持续执行 ≥ 50ms 的任务(如 JS 执行、样式计算、布局、绘制等),可能造成页面卡顿。使用 PerformanceObserver 监听时需:
- 指定
entryTypes: ['longtask'] - 确保页面已加载完成(建议在
DOMContentLoaded后注册,或使用buffered: true捕获历史记录) - 每个长任务会包含触发它的
attribution(调用栈信息,含脚本 URL、行号、列号等,需开启crossOrigin配置才能获取第三方脚本详情)
示例代码:
if ('PerformanceObserver' in window) {
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach(entry => {
console.log('长任务', {
duration: entry.duration,
startTime: entry.startTime,
containerType: entry.containerType, // 'document' | 'iframe' | 'embed' | 'object'
containerSrc: entry.containerSrc,
attribution: entry.attribution // 数组,含调用栈帧(需 crossOrigin 支持)
});
// 可上报至监控系统,如:reportLongTask(entry);
});
});
observer.observe({ entryTypes: ['longtask'], buffered: true });
}
关于元素渲染(Element Timing)
element 是 Element Timing API 提出的类型,用于监听关键元素(如带 elementtiming 属性的 <img alt="JS 中怎么用 PerformanceObserver 监听长任务(Long Tasks)和元素渲染" >、<svg></svg> 或通过 performance.markElement() 标记的元素)的渲染完成时间。但当前所有浏览器均未实现该类型,调用 observer.observe({ entryTypes: ['element'] }) 会直接报错或静默失败。
替代方案:
- 对图片/资源使用
img.onload或IntersectionObserver+getBoundingClientRect()判断是否进入视口并渲染完成 - 对自定义关键元素,可用
requestIdleCallback+getComputedStyle检查offsetWidth > 0或clientHeight > 0 - 借助
PerformanceObserver监听largest-contentful-paint(LCP)作为整体渲染质量参考
注意事项与兼容性处理
实际使用中需主动降级:
- 检查
'longtask' in PerformanceObserver.supportedEntryTypes,避免在不支持的浏览器中报错 - 不要依赖
element类型,勿将其写入entryTypes数组 - 长任务的
attribution在跨域脚本中为空,需确保 script 标签含crossorigin属性,且服务端返回Access-Control-Allow-Origin - 监听器本身应轻量,避免在回调中执行耗时操作,否则可能引发新的长任务
简单封装建议
可封装一个安全的长任务监听工具:
function observeLongTasks(cb) {
if (typeof PerformanceObserver === 'undefined') return;
if (!PerformanceObserver.supportedEntryTypes?.includes('longtask')) return;
const obs = new PerformanceObserver((list) => {
list.getEntries().forEach(cb);
});
try {
obs.observe({ entryTypes: ['longtask'], buffered: true });
} catch (e) {
// 忽略不支持或权限错误
}
}
// 使用
observeLongTasks(entry => {
if (entry.duration >= 100) {
console.warn(`严重长任务:${entry.duration}ms`);
}
});


















