绘制计时

W3C 工作草案

关于本文件的更多信息
此版本:
https://www.w3.org/TR/2026/WD-paint-timing-20260324/
最新发布版本:
https://www.w3.org/TR/paint-timing/
编辑草案:
https://w3c.github.io/paint-timing/
之前版本:
历史:
https://www.w3.org/standards/history/paint-timing/
反馈:
GitHub
规范内标注
编辑者:
(Google)
(Google)
前任编辑:
(Google)
(Google)

摘要

本文档定义了一个 API,开发者可用其捕获页面加载过程中若干关键时刻(首次绘制、首次内容绘制),这些时刻对开发者具有重要意义。

文档状态

本节描述了本文档在发布时的状态。 当前 W3C 出版物列表以及本技术报告的最新修订版, 可在 W3C 标准和草案索引 中找到。

本文档由 Web 性能工作组 作为工作草案发布, 并使用 推荐标准流程。 作为工作草案发布并不意味着 W3C 及其成员的认可。

这是一个草案文档,可能随时被更新、替代或废弃。 将此文档作为非最终版本引用是不合适的。

GitHub Issues 是讨论此规范的首选方式。

本文档受 2025 年 8 月 18 日 W3C 流程文档 管辖。

本文档由根据 W3C 专利政策 运营的工作组制作。 W3C 维护了一个关于与工作组交付物相关的任何专利披露的 公开列表; 该页面还包括披露专利的说明。 如果个人实际知道某项专利,且认为该专利包含 必要权利要求, 则必须根据 W3C 专利政策第 6 节 披露相关信息。

1. 简介

本节为非规范性内容。

Web 浏览器的主要作用之一是将 HTML、CSS 和图片资源转化为用户屏幕上的像素。衡量网页性能通常涉及测量完成这些任务(即将文本或图片内容渲染到屏幕)所需的时间。虽然有许多不同的方法可以利用这些计时信息来评判页面性能或加载体验,但所有这些方法本质上都依赖于统一的时间测量方式。

本文件是一个基础规范,规定了如何作为通用机制测量绘制计时(Paint Timing)。在此基础上,定义了“首次绘制(First Paint)”和“首次内容绘制(First Contentful Paint)”等指标。其它具体的绘制测量实例可能由其他文档进一步规定。

具体而言,本规范涵盖:

1.1. 首次绘制与首次内容绘制

“加载”并非单一时刻——它是一种体验,没有任何单一指标能够完全描述。加载体验过程中有多个时刻会影响用户对“快”或“慢”的感知。

首次绘制(FP)是这些关键时刻中的第一个,紧随其后的是首次内容绘制(FCP)。这些指标标记了浏览器渲染特定文档的时间点。对用户来说,这很重要,因为它回答了“页面是不是开始有动静了?”这一问题。

两者的主要区别在于:FP 标志着浏览器首次为特定文档渲染任何内容的时刻;而 FCP 标志着浏览器首次从 DOM 渲染出图片或文本内容的时刻。

1.2. 用法示例

const observer = new PerformanceObserver(function(list) {
    const perfEntries = list.getEntries();
    for (const perfEntry of perfEntries) {
        // 处理条目
        // 上报分析和监控
        // ...
    }
});

// 注册观察者以获取绘制计时通知
observer.observe({entryTypes: ["paint"]});

2. 术语

绘制(Paint):当用户代理将渲染树转换为屏幕上的像素时,即执行了“绘制”(或“渲染”)。正式地讲,当用户代理执行了事件循环中的 更新渲染步骤时,视为已“渲染”文档。

注意:渲染管线非常复杂,时间戳应为用户代理在该管线中能够记录到的最新时间戳(尽力而为)。通常建议此 API 采用提交帧给操作系统用于显示的时间。

当以下条件全部满足时,生成内容伪元素可绘制伪元素

当以下条件全部满足时,CSS 图像 img有内容的图像(contentful image)

DOMString 至少包含一个非文档空白字符的字符时,视为非空(non-empty)

当以下任一条件满足时,元素 target有内容(contentful)

当下列之一成立时,元素可计时(timing-eligible)

要计算可绘制包围矩形(paintable bounding rect),请对元素 target执行以下步骤:

  1. boundingRect 为在 target 上运行 getBoundingClientRect() 的结果。

  2. 文档滚动区域 剪裁 boundingRect

  3. 返回 boundingRect

注意:overflow: scrolloverflow: hidden 包含的元素,其可绘制包围矩形不会被裁剪,因为这两种情况下元素都可以通过滚动变为可见。

当以下条件全部满足时,元素 el可绘制(paintable)

首次绘制条目包含一个 DOMHighResTimeStamp ,用于报告用户代理在导航后首次渲染的时间。此时间不包括默认背景绘制,但包括非默认背景绘制及 iframe 的外包框。这是开发者关心的页面加载第一个关键时刻——用户代理已开始渲染页面的时刻。

当以下任一条件满足时,浏览上下文 ctx可绘制计时(paint-timing eligible)

3. Paint Timing 混入

本节是非规范性的。

PaintTimingMixin 接口公开了与渲染周期相关的时间戳。 它被包含在扩展了 平台对象 的接口中,例如 PerformanceEntry, 特别是 PerformanceElementTimingLargestContentfulPaintPerformanceEventTimingPerformancePaintTiming、 和 PerformanceLongAnimationFrameTiming

paintTime 属性表示 更新渲染循环结束时的时间戳, 而 presentationTime 表示帧呈现给用户时的特定实现时间戳。 在 HTML 标准中从 更新渲染调用的 标记 paint timing 算法会填充这两个属性。

依赖于绘制时序的条目中的属性,比如 LargestContentfulPaintrenderTime (以及它的 startTime), 通常返回默认绘制时间戳而不是具体的某个时间戳, 这样可以不受 presentationTime 这种具体实现细节的影响。

3.1. PaintTimingMixin 接口

[Exposed=Window]
interface mixin PaintTimingMixin {
    readonly attribute DOMHighResTimeStamp paintTime;
    readonly attribute DOMHighResTimeStamp? presentationTime;
};

包含 PaintTimingMixin 接口混入的对象具有一个关联的 paint timing 信息(null 或 paint timing 信息)。

paint timing 信息 是一个 结构体。它具有以下 条目

渲染更新结束时间

一个 DOMHighResTimeStamp

实现自定义的呈现时间

Null 或一个 DOMHighResTimeStamp

paintTime 属性的 getter 步骤是返回 thispaint timing 信息渲染更新结束时间

presentationTime 属性的 getter 步骤(如果存在)是返回 thispaint timing 信息实现定义的呈现时间

获取 默认 paint 时间戳 的步骤,对于 paint timing 信息 paintTimingInfo,返回 paintTimingInfo实现定义的呈现时间(如果非 null),否则返回 paintTimingInfo渲染更新结束时间

4. PerformancePaintTiming 接口

[Exposed=Window]
interface PerformancePaintTiming : PerformanceEntry {
    [Default] object toJSON();
};
PerformancePaintTiming includes PaintTimingMixin;

PerformancePaintTiming 扩展了 PerformanceEntry 接口的以下属性:

注意: 实现 PerformancePaintTiming 的用户代理需要在某个 全局对象"paint" 被包含在 supportedEntryTypes 中, 且该对象的 浏览上下文绘制时机可用的。 这允许开发者检测某个 浏览上下文是否支持绘制时机。

5. 处理模型

5.1. 关联图片请求

每个 Element 都有一个 关联图片请求,它是一个 图片请求或 null,初始为 null。

当某个 Element element 的处理模型为以下类型: HTMLImageElementSVGImageElement, 或 HTMLVideoElement 创建新的图片资源(例如用于显示图片或海报图片), element关联图片请求会被设置为所创建图片资源的 图片请求

注意: 每一个从 URL 获取且 scheme 等于 "data" 的图片资源, 都有一个关联的 图片请求,它不会被抓取但仍需要被加载。此请求可以作为 Element关联图片请求

注意: 当前描述较为模糊,因为未指定具体算法。当相关处理模型更统一后,可进一步严格化。

每个 Element 都有一个 关联背景图片请求列表,初始为空数组。当 Element element 的样式需要新的图片资源(用于显示为背景图片),由新资源创建的 图片请求会被添加到 element关联背景图片请求列表中。

注意: 一个 Element 可以有多个 图片请求,例如其 background-image 属性有多个值。例如下例中,一个 background-image 属性会产生四个 图片请求,这些请求都会被下述算法记录和报告。

<!DOCTYPE html>
<style>
div {
  background-image: url(https://images.example/background1.png),
                    url(https://images.example/background2.png);
}
</style>
<div></div>
<div></div>

5.2. 记录绘制计时

待处理图片记录是一个结构体,包含以下

每个 Element 都有一个拥有的文本节点集合(set of owned text nodes),为Text 节点组成的有序集合,初始为空。

每个 Document 都有一个已上报绘制集合(set of previously reported paints),为字符串有序集合,初始为空。

每个 Document 都有一个待渲染图片列表(images pending rendering),为待处理图片记录(pending image record)列表,初始为空。

每个 Document 都有一个已渲染文本元素集合(set of elements with rendered text),为Element有序集合,初始为空。

5.2.1. 对 CSS 规范的修改

每当 Element element关联背景图片请求(associated background image requests)中的某个图片请求(image request)变为完全可用时,执行处理已加载完成图片(process an image that finished loading)算法,参数为 element 和该图片请求。

5.2.2. 对 HTML 规范的修改

Element element关联图片请求(associated image request)变为完全可用时,执行处理已加载完成图片算法,参数为 element 及其关联图片请求。

当用户代理首次绘制 Text 节点 text 时,应执行以下步骤:

5.2.3. 处理已加载完成图片

处理已加载完成图片(process an image that finished loading),给定 Element element图片请求 imageRequest,按如下步骤:

  1. rootelement根节点(root)

  2. root 不是 Document,则返回。

  3. nowelement相关全局对象(relevant global object)下的当前高精度时间

  4. record待处理图片记录,其 elementelementrequestimageRequestloadTimenow

  5. record 添加到 root待渲染图片列表中。

5.3. 上报绘制计时

5.3.1. 首次内容绘制

若要判断 文档 document 是否应报告首次内容绘制,请执行以下步骤:
  1. 如果 document已报告绘制集合 包含 "first-contentful-paint",则返回 false。

  2. 如果 document 至少包含一个同时为 可绘制有内容元素,则返回 true。

  3. 否则,返回 false。

5.3.2. 标记绘制计时

当需要针对 mark paint timing(标记绘制时序), 并以 文档(Document) document 作为输入时,执行以下步骤:
  1. 如果 document浏览上下文具备绘制时序资格, 则返回。

  2. paintTimingInfo 为一个新的 绘制时序信息(paint timing info),其 渲染更新结束时间document相关全局对象 上的 当前高精度时间

  3. paintedImages 为一个新的 有序集合(ordered set)

  4. paintedTextNodes 为一个新的 有序集合

  5. 对于 doc待渲染图片列表中的每个 record

    1. 如果 record请求 可用 且已准备好被绘制,则执行以下步骤:

      1. record 追加到 paintedImages

      2. doc待渲染图片列表中移除 record

  6. 对于 doc所有后代中的每个 Element element

    1. 如果 element 已包含于 doc已绘制文本元素集合(set of elements with rendered text),则继续。

    2. 如果 element所有权文本节点集合为空,则继续。

    3. element 追加到 doc已绘制文本元素集合

    4. element 追加到 paintedTextNodes

  7. reportedPaintsdocument已报告绘制集合

  8. frameTimingInfodocument当前帧时序信息(current frame timing info)

  9. document当前帧时序信息 设为 null。

  10. flushPaintTimings 为以下步骤:

    1. 如果 reportedPaints 不包含 "first-paint",且用户代理配置为标记首次绘制,则基于 document"first-paint"paintTimingInfo 报告绘制时序

      注意: 首次绘制不包括默认背景绘制,但包括非默认背景绘制。

      此处应改为规范性注记。

    2. 如果 document 应报告首次内容绘制,则:

      1. document"first-contentful-paint"paintTimingInfo 调用 报告绘制时序

      注意: 父 frame 不应感知其子 iframe 的绘制事件,反之亦然。这意味着仅包含 iframes 的 frame 会标记首次绘制(因包含了 iframe 的外包框),但不会标记首次内容绘制

      注意: 并不保证文档一定会标记 "first-paint""first-contentful-paint"。一个完全空白的文档可能永远不会标记首次绘制,而只包含非内容元素的文档可能永远不会标记首次内容绘制

      注意: 是否标记首次绘制 是可选的。实现绘制时序的 user-agent 至少应标记首次内容绘制

    3. documentpaintTimingInfopaintedImagespaintedTextNodes 调用 报告最大内容绘制(largest contentful paint)

    4. documentpaintTimingInfopaintedImagespaintedTextNodes 调用 报告元素绘制(element timing)

    5. 如果 frameTimingInfo 非 null,则以 documentframeTimingInfopaintTimingInfo 调用 排入长动画帧条目队列(queue a long animation frame entry)

  11. 如果 user-agent 不支持实现自定义的呈现时间,则调用 flushPaintTimings 并返回。

  12. 按以下步骤 并行运行:

    1. 等待实现自定义的某个时刻,直到当前帧已向用户呈现为止。

    2. paintTimingInfo实现自定义的呈现时间 设为 document相关全局对象 上的 当前高精度时间

    3. 如果 document跨源隔离能力 为 false,则:

      1. paintTimingInfo实现自定义的呈现时间 粗化为下一个 4 毫秒的倍数或更粗粒度。

      2. 等待,直到 当前高精度时间paintTimingInfo实现自定义的呈现时间

    4. document相关全局对象为参数,向 performance timeline 任务源 排队一个全局任务,用于执行 flushPaintTimings

5.3.3. 上报绘制计时

要根据参数 documentpaintType绘制计时信息(paint timing info) paintTimingInfo 执行 上报绘制计时,请执行以下步骤:
  1. 创建一个新的 PerformancePaintTiming 对象 newEntry,位于 document相关 realm,并按如下设置其属性:

    1. 设置 newEntryname 属性为 paintType

    2. 设置 newEntryentryType 属性为 "paint"

    3. 设置 newEntrystartTime 属性为 默认绘制时间戳(default paint timestamp),参数为 paintTimingInfo

    4. 设置 newEntryduration 属性为 0。

  2. 设置 newEntry绘制计时信息(paint timing info)paintTimingInfo

  3. newEntry 加入队列document相关 realm

  4. paintType 添加到 document已上报绘制集合中。

5.4. 通用算法

5.4.1. 对绘制计时暴露

要判断一个 元素(Element) element 是否为绘制时序公开, 给定一个 文档(Document)或 null document,请执行以下步骤:

  1. 如果 element连接,返回 false。

  2. 如果 document 为 null,则令 documentelement相关设置对象(relevant settings object)相关全局对象关联文档

  3. 如果 document 不是完全激活,返回 false。

  4. 如果 element根节点不等于 document,返回 false。

  5. 返回 true。

6. 致谢

特别感谢所有贡献者,他们的技术意见和建议促使本规范不断完善。

一致性

文档约定

一致性要求通过描述性断言和 RFC 2119 术语组合表达。 规范性部分中,“必须(MUST)”、“不得(MUST NOT)”、“要求(REQUIRED)”、“应当(SHALL)”、“不应当(SHALL NOT)”、“应该(SHOULD)”、“不应该(SHOULD NOT)”、“建议(RECOMMENDED)”、“可以(MAY)”以及“可选(OPTIONAL)”等关键词, 均应按照 RFC 2119 的定义进行解释。 但为便于阅读,本规范中未将这些词全部大写。

除非明确标注为非规范性、示例或注释,否则本规范的所有内容均为规范性内容。[RFC2119]

本规范中的示例以“例如”开头,或通过 class="example" 与规范性文本区分,形式如下:

这是一个信息性示例。

信息性注释以“注”开头,并通过 class="note" 与规范性文本区分,形式如下:

注:这是一个信息性注释。

符合规范的算法

以命令式表述的算法要求(如“去除所有前导空格字符”或“返回 false 并中止这些步骤”), 其解释应结合引入算法时使用的关键词(如“必须”、“应该”、“可以”等)。

以算法或特定步骤形式提出的一致性要求,可以通过任何方式实现,只要最终结果等价即可。 特别地,本规范定义的算法旨在便于理解,而非强调性能。 鼓励实现者进行优化。

索引

本规范定义的术语

引用定义的术语

参考文献

规范性引用

[CSS-BACKGROUNDS-3]
Elika Etemad;Brad Kemper。CSS 背景与边框模块 3 级。2024年3月11日。CRD。URL:https://www.w3.org/TR/css-backgrounds-3/
[CSS-CASCADE-5]
Elika Etemad;Miriam Suzanne;Tab Atkins Jr.。CSS 级联与继承 5 级。2022年1月13日。CR。URL:https://www.w3.org/TR/css-cascade-5/
[CSS-COLOR-3]
Tantek Çelik;Chris Lilley;David Baron。CSS 颜色模块 3 级。2022年1月18日。REC。URL:https://www.w3.org/TR/css-color-3/
[CSS-DISPLAY-4]
Elika Etemad;Tab Atkins Jr.。CSS 显示模块 4 级。2025年11月6日。WD。URL:https://www.w3.org/TR/css-display-4/
[CSS-FONTS-4]
Chris Lilley。CSS 字体模块 4 级。2026年3月3日。WD。URL:https://www.w3.org/TR/css-fonts-4/
[CSS-TEXT-4]
Elika Etemad 等。CSS 文本模块 4 级。2024年5月29日。WD。URL:https://www.w3.org/TR/css-text-4/
[CSS2]
Bert Bos 等。层叠样式表 2 级修订版1(CSS 2.1)规范。2011年6月7日。REC。URL:https://www.w3.org/TR/CSS2/
[CSSOM-VIEW-1]
Simon Fraser;Emilio Cobos Álvarez。CSSOM 视图模块。2025年9月16日。WD。URL:https://www.w3.org/TR/cssom-view-1/
[DOM]
Anne van Kesteren。DOM 标准。现行标准。URL:https://dom.spec.whatwg.org/
[ELEMENT-TIMING]
元素计时 API。编辑草案。URL:https://w3c.github.io/element-timing/
[HR-TIME-3]
Yoav Weiss。高精度时间。2026年3月2日。WD。URL:https://www.w3.org/TR/hr-time-3/
[HTML]
Anne van Kesteren 等。HTML 标准。现行标准。URL:https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren;Domenic Denicola。Infra 标准。现行标准。URL:https://infra.spec.whatwg.org/
[PERFORMANCE-TIMELINE]
Nicolas Pena Moreno。性能时间线。2025年5月21日。CRD。URL:https://www.w3.org/TR/performance-timeline/
[RFC2119]
S. Bradner。用于指示 RFC 需求级别的关键字。1997年3月。最佳当前实践。URL:https://datatracker.ietf.org/doc/html/rfc2119
[SELECTORS-4]
Elika Etemad;Tab Atkins Jr.。选择器 4 级。2026年1月22日。WD。URL:https://www.w3.org/TR/selectors-4/
[SVG2]
Amelia Bellamy-Royds 等。可缩放矢量图形 (SVG) 2。2018年10月4日。CR。URL:https://www.w3.org/TR/SVG2/
[WEBIDL]
Edgar Chen;Timothy Gu。Web IDL 标准。现行标准。URL:https://webidl.spec.whatwg.org/

补充性引用

[EVENT-TIMING]
Michal Mocny。事件时序 API。2026年3月19日。WD。URL:https://www.w3.org/TR/event-timing/
[LARGEST-CONTENTFUL-PAINT]
Yoav Weiss。最大内容绘制。2026年3月19日。WD。URL:https://www.w3.org/TR/largest-contentful-paint/
[LONG-ANIMATION-FRAMES]
长动画帧 API。编辑草案。URL:https://w3c.github.io/long-animation-frames/
[URL]
Anne van Kesteren。URL 标准。现行标准。URL:https://url.spec.whatwg.org/

IDL 索引

[Exposed=Window]
interface mixin PaintTimingMixin {
    readonly attribute DOMHighResTimeStamp paintTime;
    readonly attribute DOMHighResTimeStamp? presentationTime;
};

[Exposed=Window]
interface PerformancePaintTiming : PerformanceEntry {
    [Default] object toJSON();
};
PerformancePaintTiming includes PaintTimingMixin;

问题索引

此处应为规范性注释。
MDN

PerformancePaintTiming

In all current engines.

Firefox84+Safari14.1+Chrome60+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?