performanceobserver 是浏览器提供的异步监听性能条目的 api,适用于监控长任务、页面加载、内存、布局抖动等,比轮询更高效及时且不阻塞主线程;需早期初始化以捕获初始长任务,支持多类型监听与 attribution 追踪,但存在兼容性及字段缺失限制。

PerformanceObserver 是浏览器提供的用于异步监听性能条目的 API,适合监控长任务(Long Tasks)、页面加载、内存、布局抖动等指标。它比轮询 performance.getEntries() 更高效、更及时,且不会干扰主线程。
监听长任务(longtask)
长任务指执行时间超过 50ms 的任务,是导致页面卡顿的常见原因。PerformanceObserver 可以实时捕获它们:
- 注册时指定
"longtask"类型,注意需在页面早期(如中或 DOMContentLoaded 前)初始化,否则可能错过初始长任务 - 每个长任务条目包含
startTime、duration、attribution(可选,含触发该任务的脚本 URL 和函数名) - 建议对
duration > 100ms 的任务做告警或上报,避免噪音
示例代码:
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach(entry => {
if (entry.duration > 100) {
console.warn('长任务警告:', {
duration: entry.duration,
scriptUrl: entry.attribution?.[0]?.sourceURL,
functionName: entry.attribution?.[0]?.functionName
});
// 上报到监控平台...
}
});
});
observer.observe({ entryTypes: ['longtask'] });
同时监听多种性能类型
一个 PerformanceObserver 实例可监听多个 entryTypes,减少对象开销:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 支持组合类型如
['navigation', 'resource', 'paint', 'longtask'] - 回调中用
entry.entryType区分类型,再按需处理 - 注意不同类型的条目结构差异大(例如
navigation有loadEventEnd,paint有name: 'first-paint')
示例:
const obs = new PerformanceObserver(list => {
for (const entry of list.getEntries()) {
switch (entry.entryType) {
case 'paint':
if (entry.name === 'first-contentful-paint') {
console.log('FCP:', entry.startTime);
}
break;
case 'navigation':
console.log('TTI 估算:', entry.domContentLoadedEventEnd);
break;
case 'longtask':
// 同上处理
}
}
});
obs.observe({ entryTypes: ['paint', 'navigation', 'longtask'] });
注意事项与兼容性
实际使用中需留意以下关键点:
- 浏览器支持:Chrome 59+、Edge 79+、Firefox 72+(Safari 15.4+ 支持 longtask,但 attribution 为空)
- attribution 字段非必填:仅当任务由脚本直接触发且未被 Promise/async 包裹时才可能有值;Webpack 打包、React 事件回调等常无法获取准确 source
-
不要阻塞主线程:Observer 回调本身应在 1ms 内完成,复杂逻辑建议用
queueMicrotask或setTimeout(..., 0)延后 -
避免重复注册:多次调用
observe()会覆盖之前配置;如需动态增删类型,先disconnect()再重新 observe
结合 PerformanceTimeline 做深度分析
PerformanceObserver 提供的是“流式通知”,若需回溯历史或聚合统计,可配合 performance.getEntriesByType() 使用:
- 在页面卸载前(
beforeunload)或定时快照,收集已发生的 longtask 总数、最大耗时、分布区间 - 与自定义标记(
performance.mark())结合,定位特定业务逻辑的耗时瓶颈 - 注意:getEntriesByType 不包含 observer 已消费但尚未被清除的条目,建议统一用 observer 收集 + 缓存数组管理
例如缓存所有长任务供后续分析:
const longTasks = [];
const obs = new PerformanceObserver(list => {
list.getEntries().forEach(entry => {
longTasks.push({ ...entry });
});
});
obs.observe({ entryTypes: ['longtask'] });
// 后续可:console.table(longTasks.sort((a,b) => b.duration - a.duration).slice(0,10));
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










