资源计时

W3C 候选推荐草案(Candidate Recommendation Draft),

更多关于本文档的信息
本版本:
https://www.w3.org/TR/2026/CRD-resource-timing-20260901/
最新发布版本:
https://www.w3.org/TR/resource-timing/
编辑草稿:
https://w3c.github.io/resource-timing/
以往版本:
历史记录:
https://www.w3.org/standards/history/resource-timing/
反馈意见:
public-web-perf@w3.org 主题格式为 “[resource-timing] … 消息主题 …” (邮件档案)
GitHub
实施报告:
https://w3c.github.io/test-results/resource-timing/all.html
编辑者:
Yoav Weiss (Shopify)
(Google)
前任编辑者:
Ilya Grigorik (Google)
(微软公司)
(Google Inc.)
(微软公司)
Zhiheng Wang (Google Inc.)
Anderson Quach (微软公司)

摘要

本规范定义了一个接口,使 Web 应用能够访问文档中资源的完整计时信息。

本文档状态

本节描述了本文档在发布时的状态。 当前 W3C 出版物 以及本技术报告的最新修订 可在 W3C 标准与草案索引 查询。

本文档由 Web 性能工作组 作为 Recommendation track 下的 候选推荐草案 发布。 作为候选推荐草案发布并不代表 W3C 及其成员的背书。 候选推荐草案 整合了工作组计划纳入后续候选推荐快照的先前候选推荐中的变更。

本文档为草案, 可能随时被更新、替换 或废止为其他文档。 除了作为进行中的工作外,不适宜引用本文件。

GitHub Issues 是本规范讨论的优选渠道。

本文件受 2025年8月18日W3C流程文件 约束。

本文件由在 W3C 专利政策 下运作的小组制定。 W3C 维护一份 与本组交付物相关的专利公开清单 该页面还包含专利披露的说明。 任何个人若知悉其所持专利中包含 必要声明, 必须遵照 W3C 专利政策第6节 进行披露。

1. 引言

用户延迟是 Web 应用的重要质量指标。 虽然基于 JavaScript 的机制可以为应用内的用户延迟测量提供详尽的 仪表采集,但在许多情况下,它们无法提供完整的端到端延迟 全貌。本文档引入了 PerformanceResourceTiming 接口,允许 JavaScript 机制收集与文档资源相关的完整计时 信息。Navigation Timing 2 [NAVIGATION-TIMING-2] 扩展了本规范,为导航提供了 更多相关的计时信息。

例如,下列 JavaScript 展示了测量抓取(fetch)一个资源所花时间的基本方法:

<!doctype html>
<html>
  <head>
  </head>
  <body onload="loadResources()">
    <script>
        function loadResources()
        {
          var start = new Date().getTime();
          var image1 = new Image();
          var resourceTiming = function() {
              var now = new Date().getTime();
              var latency = now - start;
              alert("End to end resource fetch: " + latency);
          };

          image1.onload = resourceTiming;
          image1.src = 'https://www.w3.org/Icons/w3c_main.png';
        }
    </script>
    <img src="https://www.w3.org/Icons/w3c_home.png">
  </body>
</html>

虽然此脚本可以测出获取一个资源所用的时间, 但它无法细分各个阶段的耗时。此外, 脚本也无法轻松测量那些在标记(markup)中描述的资源加载耗时。

为满足对用户体验完整信息的需求,本文档引入了 PerformanceResourceTiming 接口。 该接口允许 JavaScript 机制在应用中提供完整的 客户端延迟测量。有了该接口,上例可以修改为度量用户实际感知到的 资源加载时间。

下列脚本会计算页面上每个资源的抓取耗时,即便这些资源定义在标记中。 此例假定页面托管在 https://www.w3.org 上。还可以利用 PerformanceResourceTiming 接口进一步详细测量抓取每个资源各阶段所用时间。

<!doctype html>
<html>
  <head>
  </head>
  <body onload="loadResources()">
    <script>
      function loadResources()
      {
          var image1 = new Image();
          image1.onload = resourceTiming;
          image1.src = 'https://www.w3.org/Icons/w3c_main.png';
      }

      function resourceTiming()
      {
          var resourceList = window.performance.getEntriesByType("resource");
          for (i = 0; i < resourceList.length; i++)
          {
              if (resourceList[i].initiatorType == "img")
              {
                alert("End to end resource fetch: " + (resourceList[i].responseEnd - resourceList[i].startTime));
              }
          }
      }
    </script>
    <img id="image0" src="https://www.w3.org/Icons/w3c_home.png">
  </body>
</html>

2. 术语

当 Foo 实际上是一个接口时,"a Foo object"(一个 Foo 对象) 有时用于代指更准确的 "an object implementing the interface Foo"(实现了接口 Foo 的对象)。

在本规范中,所有时间值都以毫秒为单位衡量, 以文档导航开始时刻为起点 [HR-TIME]。 例如, 文档导航的开始 发生在时间 0。

此时间定义基于 High Resolution Time 规范 [HR-TIME],与 Navigation Timing 规范中使用的时间定义不同。 后者以自 1970 年 1 月 1 日 0 时(UTC)起的毫秒钟数为基准 [NAVIGATION-TIMING-2]。

3. 资源计时

3.1. 简介

The PerformanceResourceTiming 接口用于便于对被 获取的 http(s) 资源进行计时测量。例如,该接口可用于 XMLHttpRequest 对象 [XHR], HTML 元素 [HTML],例如 iframe、 img、 script、 object、 embed 和 link (link 类型为 stylesheet), SVG 元素 [SVG11] (例如 svg),以及 EventSource。

3.2. 包含在 PerformanceResourceTiming 接口中的资源

本节为非规范性内容。

由非空 client 发起的资源 Request 的 fetch, 会作为 PerformanceResourceTiming 对象包含在该 client 的 全局对象 的 性能时间线(Performance Timeline),除非在 fetch 过程中被从时间线中排除。来自 HTTP 缓存的资源会作为 PerformanceResourceTiming 对象包含在 性能时间线 中。那些已发起 fetch 但随后被中止(例如因网络错误)的资源,也会作为 PerformanceResourceTiming 对象包含在 性能时间线 中,并带有它们的开始和结束时间。

示例:

  • 如果两个 HTML IMG 元素使用相同的规范化 URL 作为 src 属性,则由第一个 HTML IMG 元素发起的该资源的 fetch 会作为一个 PerformanceResourceTiming 对象包含在 性能时间线 中。用户代理可能不会为第二个 HTML IMG 元素重新请求该 URL,而是使用为第一个 HTML IMG 元素已启动的现有下载。在这种情况下,由第一个 IMG 元素发起的该资源的 fetch 将是 性能时间线 中的唯一条目。
  • 如果通过脚本更改了 HTML IMG 元素的 src 属性, 则原始资源的 fetch 以及新 URL 的 fetch 都会作为 PerformanceResourceTiming 对象包含在 性能时间线 中。
  • 如果通过标记添加了一个 HTML IFRAME 元素且未指定 src 属性,用户代理可能会为该 IFRAME 加载 about:blank 文档。如果稍后通过脚本动态更改了 src 属性,用户代理可能会为该 IFRAME 的新 URL 发起 fetch。在这种情况下,只有该新 URL 的 fetch 会作为一个 PerformanceResourceTiming 对象包含在 性能时间线 中。
  • 如果同一规范化 URL 的 XMLHttpRequest 被生成两次,则该资源的两次 fetch 都会作为一个 PerformanceResourceTiming 对象包含在 性能时间线 中。这是因为第二个 XMLHttpRequest 的该资源的 fetch 不能重用为第一个 XMLHttpRequest 发起的下载。
  • 如果页面上包含一个 HTML IFRAME 元素,则只有由该 IFRAME 的 src 属性请求的资源会作为 PerformanceResourceTiming 对象包含在父文档的 性能时间线 中。该 IFRAME 文档请求的子资源会包含在该 IFRAME 文档的 性能时间线 中,而不是父文档的 性能时间线 中。
  • 如果 HTML IMG 元素的源是一个 data: URI(参见 [RFC2397]),则该资源不会作为 PerformanceResourceTiming 对象包含在 性能时间线 中。PerformanceResourceTiming 条目仅针对 http(s) 资源报告。
  • 如果某个资源的 fetch 因网络错误(例如 DNS、TCP 或 TLS 错误)而被中止,则该 fetch 会作为一个 PerformanceResourceTiming 对象包含在 性能时间线 中,并且仅设置 startTime、 fetchStart、duration 和 responseEnd。
  • 如果某个资源的 fetch 因不满足 fetch 前提(例如 混合内容、CORS 限制、CSP 策略等)而被中止,则该资源不会作为一个 PerformanceResourceTiming 对象包含在 性能时间线 中。

3.3. PerformanceResourceTiming 接口

[Exposed=(Window,Worker)]
interface PerformanceResourceTiming : PerformanceEntry {
    readonly attribute DOMString initiatorType;
    readonly attribute DOMString deliveryType;
    readonly attribute ByteString nextHopProtocol;
    readonly attribute DOMHighResTimeStamp workerStart;
    readonly attribute DOMHighResTimeStamp redirectStart;
    readonly attribute DOMHighResTimeStamp redirectEnd;
    readonly attribute DOMHighResTimeStamp fetchStart;
    readonly attribute DOMHighResTimeStamp domainLookupStart;
    readonly attribute DOMHighResTimeStamp domainLookupEnd;
    readonly attribute DOMHighResTimeStamp connectStart;
    readonly attribute DOMHighResTimeStamp connectEnd;
    readonly attribute DOMHighResTimeStamp secureConnectionStart;
    readonly attribute DOMHighResTimeStamp requestStart;
    readonly attribute DOMHighResTimeStamp finalResponseHeadersStart;
    readonly attribute DOMHighResTimeStamp firstInterimResponseStart;
    readonly attribute DOMHighResTimeStamp responseStart;
    readonly attribute DOMHighResTimeStamp responseEnd;
    readonly attribute DOMHighResTimeStamp workerRouterEvaluationStart;
    readonly attribute DOMHighResTimeStamp workerCacheLookupStart;
    readonly attribute DOMString workerMatchedRouterSource;
    readonly attribute DOMString workerFinalRouterSource;
    readonly attribute unsigned long long  transferSize;
    readonly attribute unsigned long long  encodedBodySize;
    readonly attribute unsigned long long  decodedBodySize;
    readonly attribute unsigned short responseStatus;
    readonly attribute RenderBlockingStatusType renderBlockingStatus;
    readonly attribute DOMString contentType;
    readonly attribute DOMString contentEncoding;
    [Default] object toJSON();
};

一个 PerformanceResourceTiming 具有一个关联的 DOMString initiator type。

一个 PerformanceResourceTiming 具有一个关联的 DOMString delivery type。

一个 PerformanceResourceTiming 具有一个关联的 DOMString 请求的 URL。

一个 PerformanceResourceTiming 具有一个关联的 DOMString 缓存模式 (空字符串、"local",或 "validated")。

一个 PerformanceResourceTiming 具有关联的 fetch timing info,该项 计时信息。

一个 PerformanceResourceTiming 具有关联的 响应正文信息,该项 资源信息。

一个 PerformanceResourceTiming 具有关联的 状态 响应状态。

一个 PerformanceResourceTiming 具有关联的 RenderBlockingStatusType 阻塞渲染状态(render-blocking status)。

当调用 toJSON 时,应为 PerformanceResourceTiming 运行 默认的 toJSON 步骤。

initiatorType getter 的步骤是返回 发起者类型,该类型对应于 this。

initiatorType 返回以下某一值:

  • "navigation":如果该请求是一个 导航请求;
  • "body":如果该请求是处理 body 元素上已废弃的 background 属性的结果。
  • "css":如果该请求是处理 CSS url() 指令的结果,例如 @import url() 或 background: url(); [CSS-VALUES]

    注意:通过 CSS 中的 @font-face 指定的字体资源请求属于处理 CSS 指令的结果。因此,该字体资源的 initiatorType 为 "css"。

  • "script":如果该请求是加载任何 脚本 的结果(包括传统脚本 script、模块脚本 module script,或 Worker)。
  • "xmlhttprequest":如果该请求是处理 XMLHttpRequest 的结果;
  • "font":如果该请求是处理字体的结果。这可能发生在字体请求后续资源时,例如使用增量字体传输(Incremental Font Transfer)[INCREMENTAL_FONT_TRANSFER] 的情况。
  • "fetch":如果该请求是处理 fetch() 方法的结果;
  • "beacon":如果该请求是处理 sendBeacon() 方法的结果; [BEACON]
  • "video":如果该请求是处理 video 元素的 poster 或 src 的结果。
  • "audio":如果该请求是处理 audio 元素的 src 的结果。
  • "track":如果该请求是处理 track 元素的 src 的结果。
  • "img":如果该请求是处理 img 元素的 src 或 srcset 的结果。
  • "image":如果该请求是处理 image 元素的结果。 [SVG2]
  • "input":如果该请求是处理某个 input 元素(其 type 为 image)的结果。
  • "ping":如果该请求是处理 a 元素的 ping 的结果。
  • "iframe":如果该请求是处理 iframe 的 src 的结果。
  • "frame":如果该请求是加载一个 frame 的结果。
  • "embed":如果该请求是处理 embed 元素的 src 的结果。
  • "link":如果该请求是处理 link 元素的结果。
  • "object":如果该请求是处理 object 元素的结果。
  • "early-hints":如果该请求是处理 Early Hints [EARLY_HINTS] 响应的结果。
  • "other":如果上述条件都不匹配。

initiatorType 的设置是在报告资源计时条目的不同位置完成的,例如在 fetch 规范中。

deliveryType getter 的步骤是返回 交付类型,该类型对应于 this。

deliveryType 返回以下值之一:

  • "cache",如果 缓存模式不是空 字符串。
  • 空字符串 "",如果上述 条件均不匹配。

预计本规范未来的更新将对此进行扩展,例如 描述使用预加载资源和预取的 导航请求。

workerStart getter 的步骤是 为 this 的 计时信息的 最终 service worker 启动 时间以及 相关全局 对象调用 转换 fetch 时间戳。更多信息请参阅 HTTP 获取。

redirectStart getter 的步骤 是为 this 的 计时信息的 重定向开始时间以及 相关全局对象调用 转换 fetch 时间戳。更多信息请参阅 HTTP 重定向获取。

redirectEnd getter 的步骤 是为 this 的 计时信息的 重定向结束时间以及 相关全局对象调用 转换 fetch 时间戳。更多信息请参阅 HTTP 重定向获取。

fetchStart getter 的步骤是 为 this 的 计时信息的 重定向后开始时间以及 相关全局对象 调用 转换 fetch 时间戳。更多信息请参阅 HTTP 获取。

domainLookupStart getter 的步骤是为 this 的 计时信息的 最终连接计时信息的 域名查找开始时间以及 相关全局对象调用 转换 fetch 时间戳。更多信息请参阅 记录连接计时信息。

domainLookupEnd getter 的步骤是为 this 的 计时信息的 最终连接计时信息的 域名查找结束时间以及 相关全局对象调用 转换 fetch 时间戳。更多信息请参阅 记录连接计时信息。

connectStart getter 的步骤是 为 this 的 计时信息的 最终连接计时信息的 连接开始时间以及 相关全局对象 调用 转换 fetch 时间戳。更多信息请参阅 记录连接计时信息。

connectEnd getter 的步骤是 为 this 的 计时信息的 最终连接计时信息的 连接结束时间以及 相关全局对象调用 转换 fetch 时间戳。更多信息请参阅 记录连接计时信息。

secureConnectionStart getter 的步骤是为 this 的 计时信息的 最终连接计时信息的 安全连接开始 时间以及 相关全局对象调用 转换 fetch 时间戳。更多信息请参阅 记录连接计时信息。

nextHopProtocol getter 的步骤是对 this 的 计时信息的 最终连接计时信息的 ALPN 协商协议进行 同构解码。更多信息请参阅 记录连接 计时信息。

Issue 221 建议 移除对 nextHopProtocol 的支持,因为它可能会泄露有关 用户网络配置的详细信息。

requestStart getter 的步骤是 为 this 的 计时信息的 最终网络请求开始 时间以及 相关全局 对象调用 转换 fetch 时间戳。更多信息请参阅 HTTP 获取。

firstInterimResponseStart getter 的步骤是 为 this 的 计时信息的 第一个临时 网络响应开始时间以及 相关 全局对象调用 转换 fetch 时间戳。更多信息请参阅 HTTP 获取。

finalResponseHeadersStart getter 的步骤是 为 this 的 计时信息的 最终网络响应开始 时间以及 相关全局 对象调用 转换 fetch 时间戳。更多信息请参阅 HTTP 获取。

responseStart getter 的步骤 是如果 this 的 firstInterimResponseStart 不为 0,则返回它;否则返回 this 的 finalResponseHeadersStart。

responseEnd getter 的步骤是 为 this 的 计时信息的 结束时间以及 相关全局对象调用 转换 fetch 时间戳。更多信息请参阅 获取。

encodedBodySize getter 的步骤是返回 this 的 资源 信息的 编码后大小。

decodedBodySize getter 的步骤是返回 this 的 资源 信息的 解码后大小。

transferSize getter 的步骤 如下:

  1. 如果 this 的 缓存 模式为 "local",则返回 0。

  2. 如果 this 的 缓存 模式为 "validated",则返回 300。

  3. 返回 this 的 资源信息的 编码后大小加 300。

    添加到 transferSize 的常数用于替代暴露 HTTP 标头的总字节大小,因为这可能会暴露 某些 cookie 的存在。参阅此 issue。

responseStatus getter 的步骤 是返回 this 的 响应 状态。

responseStatus 在 Fetch 中确定。对于 跨源 no-cors 请求, 其值将为 0,因为响应会是不透明过滤 响应。

contentType getter 的步骤是 返回 this 的 资源信息的 内容类型。

contentEncoding getter 的步骤是返回 this 的 资源 信息的 内容编码。

renderBlockingStatus getter 的步骤是,如果 this 的 计时 信息的 渲染阻塞为 true,则返回 阻塞;否则返回 非阻塞。

workerRouterEvaluationStart getter 的步骤是返回 this 的 计时 信息的 service worker 计时信息的 worker 路由器求值 开始时间。

workerCacheLookupStart getter 的步骤是返回 this 的 计时 信息的 service worker 计时信息的 worker 缓存查找开始时间。

workerMatchedRouterSource getter 的步骤是返回 this 的 计时 信息的 service worker 计时信息的 worker 匹配的路由器 来源。

workerFinalRouterSource getter 的步骤是返回 this 的 计时 信息的 service worker 计时信息的 worker 最终路由器 来源。

实现 PerformanceResourceTiming 的用户代理需要 在 supportedEntryTypes 中包含 "resource"。 这使开发者能够 检测是否支持 Resource Timing。

3.3.1. RenderBlockingStatusType 枚举

enum RenderBlockingStatusType {
    "blocking",
    "non-blocking"
};

这些值定义如下:

blocking
该资源可能阻塞渲染。
non-blocking
该资源不会阻塞渲染。

3.4. 对 Performance 接口的扩展

用户代理可以选择限制包含为 PerformanceResourceTiming 对象在 性能时间线(Performance Timeline) 中的数量 [PERFORMANCE-TIMELINE-2]。本节扩展了 Performance 接口,以允许控制所存储的 PerformanceResourceTiming 对象的数量。

推荐的 PerformanceResourceTiming 对象的最小数量为 250,但用户代理可对其进行更改。 可调用 setResourceTimingBufferSize 请求更改此限制。

每个 ECMAScript 全局环境 具有:

  • 一个 资源计时缓冲区大小限制, 初始应为 250 或更大。
  • 一个 资源计时缓冲区当前大小, 初始为 0。
  • 一个 资源计时缓冲区已满事件待定标志, 初始为 false。
  • 一个 资源计时二级缓冲区当前大小, 初始为 0。
  • 一个 资源计时二级缓冲区 用于存放 PerformanceResourceTiming 对象,初始为空。
partial interface Performance {
      undefined clearResourceTimings ();
      undefined setResourceTimingBufferSize (unsigned long maxSize);
      attribute EventHandler onresourcetimingbufferfull;
    };

Performance 接口在 [HR-TIME] 中定义。

方法 clearResourceTimings 运行以下步骤:

  1. 从 PerformanceResourceTiming 对象中删除性能条目缓冲区(performance entry buffer)中的所有条目。
  2. 将 资源计时缓冲区当前大小 设为 0。

方法 setResourceTimingBufferSize 运行以下步骤:

  1. 将 资源计时缓冲区大小限制 设为 maxSize 参数。如果 maxSize 参数小于 资源计时缓冲区当前大小,则不应从 PerformanceResourceTiming 对象中移除任何条目以缩减缓冲区。

属性 onresourcetimingbufferfull 是下文描述的 resourcetimingbufferfull 事件的事件处理器。

要检查 是否可以添加资源计时条目,按如下步骤执行:

  1. 如果 资源计时缓冲区当前大小 小于 资源计时缓冲区大小限制,则返回 true。
  2. 返回 false。

要将 PerformanceResourceTiming 条目 new entry 添加到 性能条目缓冲区,按如下步骤执行:

  1. 如果 是否可以添加资源计时条目 返回 true 且 资源计时缓冲区已满事件挂起标志 为 false,执行下列子步骤:
    1. 将 new entry 添加到 性能条目缓冲区。
    2. 将 资源计时缓冲区当前大小 增加 1。
    3. 返回。
  2. 如果 资源计时缓冲区已满事件挂起标志 为 false,执行下列子步骤:
    1. 将 资源计时缓冲区已满事件挂起标志 设为 true。
    2. 在 performance timeline 任务源 上 排队一个任务 ,以运行 触发缓冲区已满事件。
  3. 将 new entry 添加到 资源计时二级缓冲区。
  4. 将 资源计时二级缓冲区当前大小 增加 1。

要 复制二级缓冲区,按如下步骤执行:

  1. 当 资源计时二级缓冲区 不为空且 是否可以添加资源计时条目 返回 true 时,执行下列子步骤:
    1. 令 entry 为 资源计时二级缓冲区 中最早的 PerformanceResourceTiming 。
    2. 将 entry 添加到 性能条目缓冲区 的末尾。
    3. 将 资源计时缓冲区当前大小 增加 1。
    4. 从 资源计时二级缓冲区 移除 entry。
    5. 将 资源计时二级缓冲区当前大小 减 1。

要 触发缓冲区已满事件,按如下步骤执行:

  1. 当 资源计时二级缓冲区 不为空时,执行下列子步骤:
    1. 令 number of excess entries before 等于 资源计时二级缓冲区当前大小。
    2. 如果 是否可以添加资源计时条目 返回 false, 则 触发名为 resourcetimingbufferfull 的事件, 目标为 Performance 对象。
    3. 执行 复制二级缓冲区。
    4. 令 number of excess entries after 为 资源计时二级缓冲区当前大小。
    5. 如果 number of excess entries before 小于等于 number of excess entries after,则移除 资源计时二级缓冲区 中的所有条目, 将 资源计时二级缓冲区当前大小 设为 0,并 中止这些步骤。
  2. 将 资源计时缓冲区已满事件挂起标志 设为 false。

    这意味着如果 resourcetimingbufferfull 事件处理器新增缓冲区空间 小于或等于它新增的资源条目,则部分溢出条目会从缓冲区被丢弃。 开发者需确保 resourcetimingbufferfull 事件处理器调用 clearResourceTimings 或 通过调用 setResourceTimingBufferSize 适当扩展缓冲区。

3.5. 跨域资源

3.5.1. 介绍

如 Fetch 中所详述,对跨源资源的请求会 作为 PerformanceResourceTiming 对象包含在 性能时间线中。

如果对于跨源资源,计时 允许检查算法失败,则该 条目将是一个不透明条目。此类 条目的大多数属性都会被屏蔽,以防止 泄露原本不会暴露的跨源数据。因此,对于 不透明条目,以下 属性将始终返回零或空字符串: redirectStart、 redirectEnd、 workerStart、 domainLookupStart、 domainLookupEnd、 connectStart、 connectEnd、 requestStart、 firstInterimResponseStart、 finalResponseHeadersStart、 responseStart、 secureConnectionStart, 以及 nextHopProtocol。

某些属性,例如 contentType、 encodedBodySize, 以及 decodedBodySize 在响应为 CORS 跨源时会被设置为零(对于 contentType 则设置为空字符串)。

transferSize 同时受到 计时 允许检查和 CORS 跨源 状态的影响。

对于由 service worker 使用 respondWith() 处理的请求,所报告的计时数据反映的是 客户端与 service worker 之间的交互,而不是 service worker 自身的内部网络活动。例如, service worker 可能用一个跨源响应来响应同源请求, 也可能反过来,或者为任一请求返回缓存的或合成的 响应。因此,由 service worker 转发的资源并不能完整反映获取资源的整个过程,并且 不会经过计时 允许检查。要获得这些获取操作的完整信息, 可以检查 service worker 自身的性能时间线。 [SERVICE-WORKERS]

有关更多详细信息,请参阅 HTTP 获取 #4 —— 计时 允许检查仅在没有来自 service worker 的响应时执行。此外,在 respondWith() 算法中克隆的响应不会携带内部获取操作的 fetch 计时信息,因为该 信息附加到一次 fetch 上,而不是附加到一个响应上。

3.5.2. Timing-Allow-Origin 响应头

服务器端应用可以返回 Timing-Allow-Origin HTTP 响应头,以允许用户代理向指定的文档源完整地公开那些因跨域限制而被置为零的属性值。

Timing-Allow-Origin HTTP 响应头字段可用于传达一项策略,指示允许哪些源查看那些因跨域限制而被置为零的属性值。该头的值以如下 ABNF 表示(使用 List Extension,与 [RFC5234] 配合使用,以及 列表扩展 与 [RFC9110]):

Timing-Allow-Origin = 1#( origin-or-null / wildcard )

发送方可以生成多个 Timing-Allow-Origin 头字段。接收方可以通过将后续每个字段值按顺序追加并以逗号分隔的方式组合多个 Timing-Allow-Origin 头字段值。

即便存在 Timing-Allow-Origin HTTP 响应头字段,用户代理仍可能强制执行跨域限制并将 transferSize、encodedBodySize 和 decodedBodySize 属性设为零。如果这样做,它也可能将 deliveryType 设为 ""。

Timing-Allow-Origin 头在 FETCH 中处理,以据此计算相关属性。

Timing-Allow-Origin 头可能作为缓存响应的一部分到达。在缓存重新验证的情况下,根据 RFC 7234,该头的值可能来自重新验证响应;如果那里没有,则可能来自原始缓存资源。

Issue 222 和 223 建议从 Timing-Allow-Origin 中移除通配符支持,以限制其使用。

3.5.3. IANA 考虑事项

本节将 Timing-Allow-Origin 注册为 临时消息头(Provisional Message Header)。

头字段名称:
Timing-Allow-Origin
适用协议:
http
状态:
provisional
作者/变更控制者:
W3C
规范文档:
§ 3.5.2 Timing-Allow-Origin Response Header

3.6. 资源计时属性

本节为非规范性内容。

下图说明了 PerformanceResourceTiming 接口定义的计时属性。括号内的属性可能在对跨域资源进行 fetch 时不可用。用户代理可能会在计时之间进行内部处理,从而允许非规范性的计时间隔。

该图说明了 PerformanceResourceTiming 接口定义的计时属性。括号内的属性表示如果资源未通过 timing allow check 算法,则这些属性可能不可用。
Resource Timing attributes

4. 创建资源计时条目

若要标记资源计时,给定一个fetch 计时信息 timingInfo, 一个 DOMString requestedURL, 一个 DOMString initiatorType, 一个全局对象 global, 一个字符串 cacheMode, 一个响应体信息 bodyInfo, 一个状态 responseStatus,还有一个可选的字符串 deliveryType (默认为空字符串),请执行以下步骤:

  1. 在 global 的realm中, 创建一个 PerformanceResourceTiming 对象 entry。
  2. 为 entry,以及 initiatorType、requestedURL、timingInfo、 cacheMode、bodyInfo、responseStatus 和 deliveryType 设置资源计时条目。
  3. 将 PerformanceEntry entry 排队。
  4. 添加 entry 到 global 的 性能条目缓冲区。

若要为 PerformanceResourceTiming entry 设置资源计时条目, 给定 DOMString initiatorType,DOMString requestedURL, fetch 计时信息 timingInfo,一个 DOMString cacheMode, 响应体信息 bodyInfo, 一个状态 responseStatus,以及一个可选的 DOMString deliveryType(默认为空字符串),请执行以下步骤:

  1. 断言 cacheMode 是空字符串、"local" 或 "validated"。
  2. 令 global 为 entry 的 相关全局对象。
  3. 初始化 entry,传入 转换 timingInfo 的 开始时间(以 global 为准)、 "resource"、requestedURL,以及 转换 timingInfo 的 结束时间(以 global 为准)的结果。
  4. 将 entry 的 发起者类型 设为 initiatorType。
  5. 将 entry 的 请求 URL 设为 requestedURL。
  6. 将 entry 的 计时信息 设为 timingInfo。
  7. 将 entry 的 资源信息 设为 bodyInfo。
  8. 将 entry 的 缓存模式 设为 cacheMode。
  9. 将 entry 的 响应状态 设为 responseStatus。
  10. 如果 deliveryType 是空字符串且 cacheMode 非空, 则将 deliveryType 设为 "cache"。
  11. 将 entry 的 分发类型 设为 deliveryType。

要转换 fetch 时间戳,给定 DOMHighResTimeStamp ts 和 全局对象 global,执行如下步骤:

  1. 如果 ts 为零,返回零。
  2. 否则,返回以 ts 和 global 计算得到的 相对高分辨率粗略时间。

5. 安全性注意事项

PerformanceResourceTiming 接口会将某一资源的计时信息暴露给任何请求该资源的网页或 worker。为限制对此 PerformanceResourceTiming 接口的访问,默认会强制执行 同源策略,并如HTTP fetch所述,将某些属性设为零。资源提供者可通过添加 Timing-Allow-Origin HTTP 响应头(指定允许访问计时信息的域名),显式允许对该资源收集全部计时信息。

6. 隐私注意事项

统计指纹识别是一个隐私问题,恶意网站可能通过测量第三方网站资源的缓存命中和未命中的计时, 来判断用户是否访问过某个第三方网站。虽然 PerformanceResourceTiming 接口为文档中的资源提供计时信息,但资源上的 load 事件已可实现有限地检测缓存命中与否,并且 HTTP Fetch 的跨域限制可防止任何额外信息的泄漏。

7. 致谢

感谢 Anne Van Kesteren、Annie Sullivan、Arvind Jain、Boris Zbarsky、Darin Fisher、Jason Weber、Jonas Sicking、James Simonsen、 Karen Anderson、Kyle Scholz、Nic Jansma、Philippe Le Hegaret、 Sigbjørn Vik、Steve Souders、Todd Reifsteck、Tony Gentilcore、William Chan 和 Alex Christensen 对本工作的贡献。

一致性

文档约定

一致性要求通过描述性断言 与 RFC 2119 术语的结合来表达。 本文档规范性部分中出现的关键字 “MUST(必须)”、“MUST NOT(不得)”、“REQUIRED(必需)”、“SHALL(应当)”、“SHALL NOT(不得)”、“SHOULD(应该)”、“SHOULD NOT(不应该)”、“RECOMMENDED(推荐)”、 “MAY(可以)” 和 “OPTIONAL(可选)” 应按 RFC 2119 的说明来解释。 但是,为了可读性, 本规范中并未将这些单词全部以大写形式出现。

本规范的全部文字均为规范性内容, 除非明确标记为非规范性、示例或注释的部分。 [RFC2119]

本规范中的示例以 “for example(例如)” 引入, 或以 class="example" 将其与规范性文本区分开来, 如下所示:

这是一个说明性示例。

说明性注释以 “Note(注)” 一词开始,并以 class="note" 将其与规范性文本区分开来, 如下所示:

注:这是一个说明性注释。

符合性算法

作为算法一部分以祈使语气表述的要求 (例如 “strip any leading space characters(去除任何前导空格字符)” 或 “return false and abort these steps(返回 false 并中止这些步骤)”) 应根据引入该算法时所用关键字的含义来解释 (如 “must/should/may” 等)。

以算法或具体步骤表述的符合性要求可以通过任意方式实现, 只要最终结果等价即可。 特别地,本规范中定义的算法旨在便于理解, 并非以性能为设计目标。 鼓励实现者进行优化。

索引

本规范定义的术语

引用中定义的术语

参考文献

规范性参考文献

[DOM]
Anne van Kesteren. DOM 标准. 现行标准。 URL: https://dom.spec.whatwg.org/
[FETCH]
Anne van Kesteren. Fetch 标准. 现行 标准。URL: https://fetch.spec.whatwg.org/
[HR-TIME]
Yoav Weiss. 高精度时间. 2026 年 3 月 24 日。 WD. URL: https://www.w3.org/TR/hr-time-3/
[HTML]
Anne van Kesteren; et al. HTML 标准. 现行标准。URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 标准. 现行标准。URL: https://infra.spec.whatwg.org/
[PERFORMANCE-TIMELINE-2]
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
[SERVICE-WORKERS]
Monica CHINTALA; Yoshisato Yanagisawa. Service Workers 夜间版. 2026 年 8 月 12 日。CRD. URL: https://www.w3.org/TR/service-workers/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL 标准. 现行 标准。URL: https://webidl.spec.whatwg.org/

非规范性引用

[BEACON]
Ilya Grigorik; Alois Reitbauer. Beacon. 2022 年 8 月 3 日。CRD. URL: https://www.w3.org/TR/beacon/
[CSS-VALUES]
Tab Atkins Jr.; Elika Etemad. CSS 值与单位 模块第 4 级. 2024 年 3 月 12 日。WD. URL: https://www.w3.org/TR/css-values-4/
[EARLY_HINTS]
早期提示. URL: https://httpwg.org/specs/rfc8297.html
[INCREMENTAL_FONT_TRANSFER]
增量字体传输. URL: https://www.w3.org/TR/IFT/
[NAVIGATION-TIMING-2]
Yoav Weiss; Noam Rosenthal. 导航计时 第 2 级. 2026 年 2 月 25 日。WD. URL: https://www.w3.org/TR/navigation-timing-2/
[RFC2397]
L. Masinter. “data” URL 方案. 1998 年 8 月。提议标准。URL: https://www.rfc-editor.org/info/rfc2397/
[RFC5234]
D. Crocker, Ed.; P. Overell. 语法规范的增强 BNF: ABNF. 2008 年 1 月。互联网标准。URL: https://www.rfc-editor.org/info/rfc5234/
[RFC9110]
R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed.. HTTP 语义. 2022 年 6 月。互联网 标准。URL: https://httpwg.org/specs/rfc9110.html
[SVG11]
Erik Dahlström; et al. 可缩放矢量图形(SVG)1.1 (第二版). 2011 年 8 月 16 日。REC. URL: https://www.w3.org/TR/SVG11/
[SVG2]
Amelia Bellamy-Royds; et al. 可缩放矢量图形(SVG) 2. 2018 年 10 月 4 日。CR. URL: https://www.w3.org/TR/SVG2/
[XHR]
Anne van Kesteren. XMLHttpRequest 标准. 现行 标准。URL: https://xhr.spec.whatwg.org/

IDL 索引

[Exposed=(Window,Worker)]
interface PerformanceResourceTiming : PerformanceEntry {
    readonly attribute DOMString initiatorType;
    readonly attribute DOMString deliveryType;
    readonly attribute ByteString nextHopProtocol;
    readonly attribute DOMHighResTimeStamp workerStart;
    readonly attribute DOMHighResTimeStamp redirectStart;
    readonly attribute DOMHighResTimeStamp redirectEnd;
    readonly attribute DOMHighResTimeStamp fetchStart;
    readonly attribute DOMHighResTimeStamp domainLookupStart;
    readonly attribute DOMHighResTimeStamp domainLookupEnd;
    readonly attribute DOMHighResTimeStamp connectStart;
    readonly attribute DOMHighResTimeStamp connectEnd;
    readonly attribute DOMHighResTimeStamp secureConnectionStart;
    readonly attribute DOMHighResTimeStamp requestStart;
    readonly attribute DOMHighResTimeStamp finalResponseHeadersStart;
    readonly attribute DOMHighResTimeStamp firstInterimResponseStart;
    readonly attribute DOMHighResTimeStamp responseStart;
    readonly attribute DOMHighResTimeStamp responseEnd;
    readonly attribute DOMHighResTimeStamp workerRouterEvaluationStart;
    readonly attribute DOMHighResTimeStamp workerCacheLookupStart;
    readonly attribute DOMString workerMatchedRouterSource;
    readonly attribute DOMString workerFinalRouterSource;
    readonly attribute unsigned long long  transferSize;
    readonly attribute unsigned long long  encodedBodySize;
    readonly attribute unsigned long long  decodedBodySize;
    readonly attribute unsigned short responseStatus;
    readonly attribute RenderBlockingStatusType renderBlockingStatus;
    readonly attribute DOMString contentType;
    readonly attribute DOMString contentEncoding;
    [Default] object toJSON();
};

enum RenderBlockingStatusType {
    "blocking",
    "non-blocking"
};

partial interface Performance {
      undefined clearResourceTimings ();
      undefined setResourceTimingBufferSize (unsigned long maxSize);
      attribute EventHandler onresourcetimingbufferfull;
    };

✔MDN

Performance/clearResourceTimings

In all current engines.

Firefox35+Safari11+Chrome46+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.jsNone
✔MDN

Performance/resourcetimingbufferfull_event

In all current engines.

Firefox35+Safari11+Chrome46+
OperaNoneEdge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.jsNone
✔MDN

Performance/setResourceTimingBufferSize

In all current engines.

Firefox35+Safari11+Chrome46+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.jsNone
✔MDN

Performance

In all current engines.

Firefox7+Safari8+Chrome6+
Opera?Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari9+Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
Node.jsNone
✔MDN

PerformanceResourceTiming/connectEnd

In all current engines.

Firefox31+Safari11+Chrome43+
Opera32+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile32+
✔MDN

PerformanceResourceTiming/connectStart

In all current engines.

Firefox31+Safari11+Chrome43+
Opera32+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile32+
✔MDN

PerformanceResourceTiming/decodedBodySize

In all current engines.

Firefox45+Safari16.4+Chrome54+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

PerformanceResourceTiming/domainLookupEnd

In all current engines.

Firefox31+Safari11+Chrome43+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

PerformanceResourceTiming/domainLookupStart

In all current engines.

Firefox31+Safari11+Chrome43+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

PerformanceResourceTiming/encodedBodySize

In all current engines.

Firefox45+Safari16.4+Chrome54+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

PerformanceResourceTiming/fetchStart

In all current engines.

Firefox31+Safari11+Chrome43+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

PerformanceResourceTiming/initiatorType

In all current engines.

Firefox31+Safari11+Chrome43+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

PerformanceResourceTiming/nextHopProtocol

In all current engines.

Firefox45+Safari11+Chrome61+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

PerformanceResourceTiming/redirectEnd

In all current engines.

Firefox31+Safari11+Chrome43+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

PerformanceResourceTiming/redirectStart

In all current engines.

Firefox31+Safari11+Chrome43+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
⚠MDN

PerformanceResourceTiming/renderBlockingStatus

In only one current engine.

FirefoxNoneSafariNoneChrome107+
Opera?Edge107+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

PerformanceResourceTiming/requestStart

In all current engines.

Firefox31+Safari11+Chrome43+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

PerformanceResourceTiming/responseEnd

In all current engines.

Firefox31+Safari11+Chrome43+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

PerformanceResourceTiming/responseStart

In all current engines.

Firefox31+Safari11+Chrome43+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
⚠MDN

PerformanceResourceTiming/responseStatus

In only one current engine.

FirefoxNoneSafariNoneChrome109+
Opera?Edge109+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

PerformanceResourceTiming/secureConnectionStart

In all current engines.

Firefox31+Safari11+Chrome43+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

PerformanceResourceTiming/toJSON

In all current engines.

Firefox34+Safari11+Chrome45+
Opera?Edge79+
Edge (Legacy)16+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

PerformanceResourceTiming/transferSize

In all current engines.

Firefox45+Safari16.4+Chrome54+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

PerformanceResourceTiming/workerStart

In all current engines.

Firefox58+Safari11+Chrome46+
Opera32+Edge79+
Edge (Legacy)16+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile32+
✔MDN

PerformanceResourceTiming

In all current engines.

Firefox31+Safari11+Chrome29+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

Headers/Timing-Allow-Origin

In all current engines.

FirefoxYesSafariYesChromeYes
Opera?EdgeYes
Edge (Legacy)NoneIE?
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?