Element Timing API 是浏览器原生性能接口,用于测量 img、svg、video、iframe 及带 elementtiming 属性的元素首次渲染时间;其 entry.duration 恒为 0,关键指标是 startTime,且仅 Chrome/Edge 支持。

Element Timing API 是什么,它能测哪些元素
Element Timing API 是浏览器原生支持的性能测量接口,用于捕获指定 DOM 元素首次渲染(paint)的时间戳。它不测加载、解析或 JS 执行时间,只关心「这个元素第一次出现在屏幕上」的时刻——也就是 first-paint for that element。
它能标记的元素类型有限:img、svg、video、iframe,以及带 elementtiming 属性的任意元素(比如 <div elementtiming="hero-banner">)。注意:纯文本节点、伪元素、CSS 生成内容(::before)都不行。
常见错误现象包括:performance.getEntriesByType('element') 返回空数组,或 entry.duration 始终为 0——通常是因为元素没加 elementtiming 属性,或元素在触发 performance.observe 之前已渲染完毕。
怎么给元素打标记并启动监听
必须显式为要测量的元素添加 elementtiming 属性,值为字符串标识符(不能含空格或特殊字符):
<img src="hero.jpg" elementtiming="hero-image">
<div elementtiming="main-title">Welcome</div>
然后用 PerformanceObserver 监听 element 类型条目:
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log(entry.name, entry.startTime, entry.duration);
}
});
observer.observe({ entryTypes: ['element'] });
关键点:
- 监听必须在元素插入 DOM 之前或同时 启动;如果页面已加载完成再调用
observe(),已渲染的元素不会触发回调(除非是动态插入的新元素) -
elementtiming属性值会成为entry.name,不是id或class - 同一页面中多个同名
elementtiming值会被分别记录,但名字重复不利于区分,建议唯一
为什么 entry.duration 总是 0,怎么判断是否真正渲染完成
entry.duration 在 Element Timing API 中**始终为 0**——这是规范定义,不是 bug。它不表示持续时间,仅保留字段。真正有意义的是 entry.startTime(相对于 navigationStart 的毫秒数),即该元素首帧渲染时间点。
判断“是否真正渲染完成”的实际做法是:
- 对比多个同类元素的
startTime,看是否符合预期顺序(如 banner 图应早于下方文字块) - 结合
entry.intersectionRect(需启用observe({ entryTypes: ['element'], buffered: true }))确认元素是否在视口内首次可见 - 若
startTime === 0,说明该元素在导航开始前就已存在且已渲染(比如 SSR 输出的静态元素),此时无法获取更细粒度时间
注意:Chrome 110+ 支持 entry.loadTime(资源加载完成时间),但它和 startTime 不同步——例如一张异步加载的图片,loadTime 可能远早于其实际绘制时间。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
立即学习“前端免费学习笔记(深入)”;
兼容性与替代方案要注意什么 Element Timing API 目前仅 Chrome 102+、Edge 102+ 原生支持,Firefox 和 Safari 尚未实现。生产环境不能单独依赖它。
如果你需要跨浏览器覆盖,得组合使用:
- 对
img/video:监听load事件 +requestIdleCallback或setTimeout(..., 0)模拟“下一帧绘制后” - 对普通容器:用
IntersectionObserver+getBoundingClientRect()判断首次进入视口,再配合performance.now()打点 - 服务端渲染场景下,可注入
renderStart时间戳到全局变量,前端用performance.mark()对齐
最易被忽略的一点:API 不会自动上报数据。你得自己在 PerformanceObserver 回调里调用 sendBeacon() 或封装成自定义指标上报逻辑,否则所有时间数据只停留在控制台。


















