绘制计时

W3C 工作草案,

关于本文件的更多信息
此版本:
https://www.w3.org/TR/2026/WD-paint-timing-20261014/
最新发布版本:
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: scroll 或 overflow: hidden 包含的元素,其可绘制包围矩形不会被裁剪,因为这两种情况下元素都可以通过滚动变为可见。

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

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

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

3. Paint Timing 混入

本节是非规范性的。

The PaintTimingMixin 接口公开与渲染周期相关的时间戳。 它包含在扩展 PerformanceEntry 的平台对象中, 具体包括 PerformanceElementTiming、 LargestContentfulPaint、 PerformanceEventTiming、 PerformancePaintTiming 和 PerformanceLongAnimationFrameTiming。

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

依赖于绘制时序的条目中的属性,比如 LargestContentfulPaint 的 renderTime (以及它的 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 步骤是返回 this 的 paint timing 信息 的 渲染更新结束时间。

presentationTime 属性的 getter 步骤(如果存在)是返回 this 的 paint 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 的处理模型为以下类型: HTMLImageElement、 SVGImageElement, 或 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. 令 root 为 element 的 根节点(root)。

  2. 若 root 不是 Document,则返回。

  3. 令 now 为 element 的 相关全局对象(relevant global object)下的当前高精度时间。

  4. 令 record 为 待处理图片记录,其 element 为 element,request 为 imageRequest,loadTime 为 now。

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

5.3. 上报绘制计时

5.3.1. 首次内容绘制

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

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

  3. 否则,返回 false。

5.3.2. 标记绘制计时

当被要求根据作为输入的 标记绘制 时间,并给定一个 Document document 时,执行以下步骤:
  1. 如果 文档的浏览上下文不符合绘制计时条件, 则返回。

  2. 令 paintTimingInfo 为一个新的绘制计时信息,其渲染更新结束时间为 以 document 的当前高精度时间,并给定 document 的相关全局对象。

  3. 令 paintedImages 为一个新的有序集合

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

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

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

      1. 将 record 追加到 paintedImages。

      2. 从 doc 的待渲染图像列表中移除 record。

  6. 对于 Element element,它是 doc 的后代之一:

    1. 如果 element 包含在 doc 的包含已渲染 文本的元素集合中,则继续。

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

    3. 追加 element 到 doc 的包含已渲染 文本的元素集合中。

    4. 将 element 追加到 paintedTextNodes 中。

  7. 令 reportedPaints 为 document 的先前已报告的绘制集合。

  8. 令 frameTimingInfo 为 document 的当前帧计时信息。

  9. 将 document 的当前帧计时信息设置为 null。

  10. 令 flushPaintTimings 为以下步骤:

    1. 如果 reportedPaints 不包含 "first-paint",且用户代理已配置为 标记首次 绘制,则报告绘制计时,并给定 document、 "first-paint" 和 paintTimingInfo。

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

      这 应当改为规范性注释。

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

      1. 报告绘制计时,并给定 document、"first-contentful-paint" 和 paintTimingInfo。

      注意: 父框架不应 感知来自其子 iframe 的绘制事件,反之亦然。这意味着 仅包含 iframe 的框架会有首次绘制(由于可绘制 iframe 的包围盒),但不会有首次内容绘制。

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

      注意: 标记首次绘制 是可选的。实现绘制计时的用户代理至少应标记首次内容绘制。

    3. 报告最大内容绘制, 并给定 document、paintTimingInfo、 paintedImages 和 paintedTextNodes。

    4. 报告元素计时,并给定 document、paintTimingInfo、 paintedImages 和 paintedTextNodes。

    5. 如果 frameTimingInfo 不为 null,则将长动画帧 条目加入队列,并给定 document、frameTimingInfo 和 paintTimingInfo。

  11. 如果用户代理不支持实现定义的呈现时间,则调用 flushPaintTimings 并返回。

  12. 并行执行以下步骤:

    1. 等待至实现定义的时间,此时当前帧已呈现给 用户。

    2. 将 paintTimingInfo 的实现定义的 呈现时间设置为当前高精度时间, 并给定 document 的相关全局对象。

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

      1. 将 paintTimingInfo 的实现定义的 呈现时间粗化到下一个 4 毫秒的倍数,或更粗的精度。

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

    4. 在排入一个全局任务到性能时间线任务 源,并给定 document 的相关全局对象,以运行 flushPaintTimings。

5.3.3. 上报绘制计时

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

    1. 设置 newEntry 的 name 属性为 paintType。

    2. 设置 newEntry 的 entryType 属性为 "paint"。

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

    4. 设置 newEntry 的 duration 属性为 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,则令 document 为 element 的 相关设置对象(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 年 9 月 13 日。WD。URL:https://www.w3.org/TR/css-fonts-4/
[CSS-TEXT-4]
Elika Etemad; 等。CSS 文本模块第 4 级。 2026 年 8 月 14 日。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 年 9 月 1 日。 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]
Karl Dubost; 等。 可缩放矢量图形(SVG)2。 2026 年 10 月 6 日。候选推荐标准(CR)。网址: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 年 10 月 13 日。WD。URL:https://www.w3.org/TR/event-timing/
[LARGEST-CONTENTFUL-PAINT]
Yoav Weiss. 最大内容绘制。2026 年 8 月 26 日。WD。URL:https://www.w3.org/TR/largest-contentful-paint/
[LONG-ANIMATION-FRAMES]
Noam Rosenthal. 长动画帧 API。2026 年 4 月 28 日。FPWD。URL:https://www.w3.org/TR/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;

Issues Index

This should be turned into a normative note. ↵
✔MDN