performance.getentriesbyname 返回空数组的主因是标记未被记录,需确保先调用 performance.mark() 且名称大小写一致、无js错误中断、同上下文执行,并注意浏览器兼容性及iframe隔离。

performance.getEntriesByName 返回空数组的常见原因
调用 performance.getEntriesByName("my-mark") 却拿不到数据,大概率不是 API 用错了,而是标记根本没被记录进去。浏览器只记录两类条目:一类是导航、资源加载等自动采集的(navigation、resource),另一类是手动打的 mark 和 measure ——但必须先用 performance.mark() 显式创建,且不能在标记之后才调用 getEntriesByName。
容易踩的坑:
-
performance.mark()必须在getEntriesByName()之前执行,且不能被 JS 错误中断(比如 mark 前抛了异常,后续代码不执行) - 名称区分大小写,
performance.mark("MyMark")和performance.getEntriesByName("mymark")不匹配 - 如果页面刷新或 iframe 重载,所有标记会被清空;跨 iframe 调用时,需确保在目标 iframe 的上下文中执行
- 某些浏览器(如旧版 Safari)对
mark支持不完整,建议检查performance.mark是否为函数
如何正确创建并查询一个性能标记
最简可行路径就是三步:检测 API、打标记、查标记。不需要额外 polyfill,现代浏览器都支持。
实操建议:
- 先确认环境:
if (performance.mark && performance.getEntriesByName) - 打标记要早于查询点,例如放在
<script></script>内联脚本中,或 DOMContentLoaded 之前 - 查询时指定类型过滤更稳妥:
performance.getEntriesByName("load-start", "mark"),第二个参数限定了只查mark类型,避免和同名 resource 条目混淆 - 返回的是数组,即使只打了一个标记也要用
[0]取值,不要假设单例
示例:
performance.mark("app-init");
// … 后续逻辑
const entries = performance.getEntriesByName("app-init", "mark");
console.log(entries[0]?.startTime); // 注意可选链,entries 可能为空
为什么有时查到多个同名标记
同一个名字可以被多次标记,performance.mark() 不会覆盖,而是追加。这在循环、重试逻辑、SPA 路由反复触发时很常见。
使用场景提示:
- 若只需最新一次,取
entries[entries.length - 1] - 若需首次,取
entries[0] - 若要排除重复干扰,打标记时拼入唯一上下文,比如
performance.mark(`render-${Date.now()}`)或performance.mark(`nav-to-${route}`) - 调试时可用
performance.getEntriesByType("mark")查看全部已记录的 mark,快速定位命名冲突
在 React/Vue 等框架中打标记的时机陷阱
框架的异步渲染机制会让 mark 位置和你预期的“DOM 就绪”时间不一致。比如在 React 的 useEffect 中打 "render-complete",实际标记的是 effect 执行时刻,而非真实绘制完成时间。
关键判断点:
- 想测 JS 执行耗时?用
mark+measure包裹逻辑块即可 - 想测首屏渲染?应结合
performance.getEntriesByType("paint")查first-contentful-paint,而不是靠人工 mark - 在 Vue
mounted或 ReactuseLayoutEffect中打点,比useEffect更接近 DOM 更新完成点,但仍不是渲染帧终点 - 真正可靠的渲染标记需要
requestIdleCallback或PerformanceObserver监听paint类型,getEntriesByName本身不解决时机精度问题
复杂点在于:标记本身廉价,但“标记代表什么”完全取决于你把它放在哪一行代码里——它不会自动理解你的业务语义。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











