为什么我的PerformanceObserver获取不到mark标记的性能数据?

哲玮(打工版) 阅读 35

我用Performance API给页面关键节点加了performance.mark()标记,但通过PerformanceObserver获取数据时一直为空,这是怎么回事?

我按照文档写了这样的代码:


performance.mark('start-render');
// 执行了一些DOM操作
performance.mark('end-render');

const observer = new PerformanceObserver(list => {
  console.log(list.getEntries()); // 这里输出空数组
});
observer.observe({ entryTypes: ['mark'] });

明明调用了mark方法,也设置了正确的entryTypes,但就是获取不到数据。我试过换成measure类型也是一样,还发现如果改成navigation类型反而能拿到导航数据。是不是有什么初始化步骤遗漏了?

我来解答 赞 7 收藏
二维码
手机扫码查看
2 条解答
シ娇娇
シ娇娇 Lv1
你这个情况很典型,问题出在时机上。PerformanceObserver 是异步监听的,而你的 mark 打点是在 observer 创建之前就执行了,所以根本监听不到。

PerformanceObserver 只会收到它创建之后才产生的性能条目,你那两个 performance.mark() 调用发生在 observer 之前,属于“历史数据”,observer 拿不到是正常的。这就像你打开录音机之前别人说的内容,当然录不进去。

标准写法应该是先注册 observer,再打点。把 observe 调用放在所有 mark 之前:

const observer = new PerformanceObserver(list => {
console.log(list.getEntries()); // 这时候就能拿到了
});
observer.observe({ entryTypes: ['mark'] });

// 然后再打点
performance.mark('start-render');
// 做些操作
performance.mark('end-render');


另外也可以考虑用 performance.getEntriesByType('mark') 直接同步读取所有已存在的 mark,但这和 Observer 的用途不一样,适合一次性采集的场景。

你提到换成 navigation 类型能拿到数据,是因为 navigation 条目生命周期早,通常在脚本执行前就已经生成了,而 observer 对这种持久条目有时能捕获到,但 mark 不行,它是严格按时间顺序的。

记住一点:Observer 必须提前注册,不然就漏数据。这是文档里强调的时序要求,不是可选的最佳实践。
点赞 5
2026-02-11 13:05
技术爱香
PerformanceObserver 默认不会捕获已存在的 mark。你需要在创建 observer 后,再打 mark,或者加上 buffered: true 选项。

const observer = new PerformanceObserver(list => {
console.log(list.getEntries());
});
observer.observe({ entryTypes: ['mark'], buffered: true });
点赞 2
2026-02-04 15:11