性能时间线

W3C 候选推荐草案

关于此文档的更多信息
此版本:
https://www.w3.org/TR/2024/CRD-performance-timeline-20240216/
最新发布版本:
https://www.w3.org/TR/performance-timeline/
最新编辑草案:
https://w3c.github.io/performance-timeline/
历史记录:
https://www.w3.org/standards/history/performance-timeline
提交历史
测试套件:
https://github.com/web-platform-tests/wpt/tree/master/performance-timeline
实施报告:
https://wpt.fyi/results/performance-timeline
编辑:
Nicolás Peña Moreno (谷歌)
前任编辑:
Ilya Grigorik (谷歌)
(微软公司) (截至2014年11月)
Zhiheng Wang (谷歌) (截至2013年7月)
反馈:
GitHub w3c/performance-timeline (拉取请求, 新问题, 开放问题)

摘要

本规范通过提供存储和检索高分辨率性能度量数据的方法,扩展了高分辨率时间规范 [HR-TIME-3]。

本文档状态

本节描述了本文档在发布时的状态。当前 W3C 出版物的列表以及此技术报告的最新版本可以在 W3C 技术报告索引 中找到,网址为 https://www.w3.org/TR/。

本性能时间线规范取代了 [PERFORMANCE-TIMELINE] 的第一个版本,并包括以下内容:

本文档由 Web 性能工作组 作为候选推荐草案使用 推荐流程 发布。

作为候选推荐发布并不意味着得到了 W3C 及其成员的认可。候选推荐草案整合了工作组计划包含在后续候选推荐快照中的前一版候选推荐的变更。

这是一个草案文档,可能随时被更新、替代或废弃。除了作为正在进行的工作外,引用此文档是不合适的。

本文件由根据 W3C 专利政策 运营的工作组制作。 W3C 维护了与该工作组交付物相关的任何专利披露的 公开列表;该页面还包括披露专利的说明。若个人实际了解包含 必要声明 的专利,则必须根据 W3C 专利政策第6节 进行披露。

本文档受 2023年11月3日 W3C 流程文档 管辖。

1. 介绍

本节为非规范性内容。

准确测量 Web 应用程序的性能特性是提高 Web 应用程序速度的重要方面。 本规范定义了必要的 性能时间线 基元,使 Web 开发人员能够访问、监测和检索 Web 应用程序整个生命周期中的各种性能指标。

[NAVIGATION-TIMING-2]、[RESOURCE-TIMING-2] 和 [USER-TIMING-2] 是定义与文档导航、页面资源和开发者脚本相关的时间信息的规范示例。 这些和其他性能接口共同定义了描述 Web 应用程序 性能时间线 的性能指标。 例如,以下脚本展示了开发人员如何访问 性能时间线 以获取与文档导航、页面资源和开发人员脚本相关的性能指标:

<!doctype html>
<html>
<head></head>
<body onload="init()">
  <img id="image0" src="https://www.w3.org/Icons/w3c_main.png" />
  <script>
    function init() {
      // 参见 [[USER-TIMING-2]]
      performance.mark("startWork");
      doWork(); // 一些开发人员代码
      performance.mark("endWork");
      measurePerf();
    }
    function measurePerf() {
      performance
        .getEntries()
        .map(entry => JSON.stringify(entry, null, 2))
        .forEach(json => console.log(json));
    }
  </script>
  </body>
</html>

或者,开发人员可以通过 性能时间线 观察新性能指标,或通过 PerformanceObserver 接口获取指定类型的先前缓冲的性能指标。

PerformanceObserver 接口被添加进来,旨在解决第一例中基于缓冲区的方法的局限性。通过使用 PerformanceObserver 接口,应用程序可以:

鼓励开发人员尽可能使用 PerformanceObserver。此外,新的性能 API 和指标可能只通过 PerformanceObserver 接口提供。观察者通过在构造函数中指定回调和通过 observe() 方法指定感兴趣的性能条目类型来工作。用户代理选择何时执行回调,回调接收已排队的性能条目。

使用 PerformanceObserver 接口时有关于初始页面加载的特殊考虑:注册必须处于活动状态才能接收事件,但注册脚本可能不可用,也可能不希望位于关键路径中。为解决这个问题,用户代理会在页面构建时缓冲一定数量的事件,并可以通过注册观察者时的 buffered 标志访问这些缓冲事件。当设置此标志时,用户代理会检索并调度其已缓冲的指定类型的事件,并在执行 observe() 调用后的第一个回调中传递它们。

注意

缓冲事件的数量由定义指标的规范决定,缓冲旨在用于前 N 个事件;缓冲不是无界或连续的。

<!doctype html>
<html>
<head></head>
<body>
<img id="image0" src="https://www.w3.org/Icons/w3c_main.png" />
<script>
// 知道我们想要使用的条目类型何时不受支持。
function detectSupport(entryTypes) {
  for (const entryType of entryTypes) {
    if (!PerformanceObserver.supportedEntryTypes.includes(entryType)) {
      // 向客户端分析指示 |entryType| 不受支持。
    }
  }
}
detectSupport(["resource", "mark", "measure"]);
const userTimingObserver = new PerformanceObserver(list => {
  list
    .getEntries()
    // 获取我们感兴趣的值
    .map(({ name, entryType, startTime, duration }) => {
      const obj = {
        "Duration": duration,
        "Entry Type": entryType,
        "Name": name,
        "Start Time": startTime,
      };
      return JSON.stringify(obj, null, 2);
    })
    // 将它们显示在控制台。
    .forEach(console.log);
  // 处理完事件后断开连接。
  userTimingObserver.disconnect();
});
// 订阅新事件以用于用户时序。
userTimingObserver.observe({entryTypes: ["mark", "measure"]});
const resourceObserver = new PerformanceObserver(list => {
  list
    .getEntries()
    // 获取我们感兴趣的值
    .map(({ name, startTime, fetchStart, responseStart, responseEnd }) => {
      const obj = {
        "Name": name,
        "Start Time": startTime,
        "Fetch Start": fetchStart,
        "Response Start": responseStart,
        "Response End": responseEnd,
      };
      return JSON.stringify(obj, null, 2);
    })
    // 将它们显示在控制台。
    .forEach(console.log);
  // 处理完事件后断开连接。
  resourceObserver.disconnect();
});
// 检索缓冲事件并订阅资源时序的较新事件。
resourceObserver.observe({type: "resource", buffered: true});
</script>
</body>
</html>

2. 一致性

与标记为非规范性的章节一样,本规范中的所有创作指南、图表、示例和注释都是非规范性的。本规范中的其他内容是规范性的。

本文档中的关键字 必须禁止应该 应按照 BCP 14 [RFC2119] [RFC8174] 中的描述进行解释,且仅当它们完全大写时,如此处所示。

以算法或特定步骤表述的一致性要求可以以任何方式实现,只要最终结果等效即可。(特别是,本规范中定义的算法旨在易于理解,而非旨在提高性能)。

3. 性能时间线

每个 全局对象 具有以下属性:

每个 文档 具有:

为了获取 相关的性能条目元组,输入 entryTypeglobalObject 时,执行以下步骤:

  1. map 为与 globalObject 关联的 性能条目缓冲区映射
  2. 返回从 map获取条目值 的结果,给定 entryType 作为

3.1 扩展 Performance 接口

这扩展了来自 [HR-TIME-3] 的 Performance 接口,并提供用于从 性能时间线 中检索性能指标数据的性能相关属性和方法。

WebIDLpartial interface Performance {
              PerformanceEntryList getEntries ();
              PerformanceEntryList getEntriesByType (DOMString type);
              PerformanceEntryList getEntriesByName (DOMString name, optional DOMString type);
            };
            typedef sequence<PerformanceEntry> PerformanceEntryList;

PerformanceEntryList 表示 PerformanceEntry 的序列,为开发人员提供了在 JavaScript 数组上可以找到的所有便捷方法。

3.1.1 getEntries() 方法

返回由 按名称和类型过滤缓冲区映射 算法返回的 PerformanceEntryList 对象,nametype 设置为 null

3.1.2 getEntriesByType() 方法

返回由 按名称和类型过滤缓冲区映射 算法返回的 PerformanceEntryList 对象,其中 name 设置为 null,而 type 设置为方法的输入 type 参数。

3.1.3 getEntriesByName() 方法

返回由 按名称和类型过滤缓冲区映射 算法返回的 PerformanceEntryList 对象,其中 name 设置为方法的输入 name 参数,type 如果省略了可选的 entryType,则设置为 null,否则设置为方法的输入 type 参数。

4. PerformanceEntry 接口

PerformanceEntry 接口包含各种性能指标的数据。

WebIDL[Exposed=(Window,Worker)]
interface PerformanceEntry {
  readonly    attribute unsigned long long  id;
  readonly    attribute DOMString           name;
  readonly    attribute DOMString           entryType;
  readonly    attribute DOMHighResTimeStamp startTime;
  readonly    attribute DOMHighResTimeStamp duration;
  readonly    attribute unsigned long long  navigationId;
  [Default] object toJSON();
};
name
此属性必须返回其初始化值。它表示此PerformanceEntry 对象的标识符。该标识符不必唯一。
entryType
此属性必须返回其初始化值。
注意

所有 entryType 值都在相关的注册表中定义。示例包括:"mark""measure" [USER-TIMING-2],"navigation" [NAVIGATION-TIMING-2], 以及 "resource" [RESOURCE-TIMING-2]。

startTime
此属性必须返回其初始化值。它表示该性能指标的第一个记录时间戳的时间值。
duration
duration 属性的 getter 步骤是: 如果this结束时间 为 0,则返回 0;否则,返回 this结束时间 减去 thisstartTime
navigationId
此属性必须返回其初始化值。

当调用 toJSON 时,执行 [WebIDL] 的 默认 toJSON 步骤

PerformanceEntry 有一个 DOMHighResTimeStamp结束时间,初始值为 0。

为了 初始化一个 PerformanceEntry entry,给定一个 DOMHighResTimeStampstartTime,一个 DOMStringentryType,一个 DOMString 的名称,和一个可选的 DOMHighResTimeStampendTime(默认值为 0):

  1. 断言:entryType 已在 条目类型注册表中定义。
  2. 初始化 entrystartTimestartTime
  3. 初始化 entryentryTypeentryType
  4. 初始化 entrynamename
  5. 初始化 entry结束时间endTime

5. PerformanceObserver 接口

PerformanceObserver 接口可以用于 观察 性能时间线,以便在记录新的性能指标时收到通知,并且可以选择缓冲的性能指标。

每个 PerformanceObserver 关联以下概念:

PerformanceObserver(callback) 构造函数必须创建一个新的 PerformanceObserver 对象, 其 观察者回调 被设置为 callback,然后返回它。

注册的性能观察者是一个由观察者成员(PerformanceObserver 对象)和选项列表成员 (一个由 PerformanceObserverInit 字典组成的列表)组成的结构体。

WebIDLcallback PerformanceObserverCallback = undefined (PerformanceObserverEntryList entries,
                                             PerformanceObserver observer,
                                             optional PerformanceObserverCallbackOptions options = {});
[Exposed=(Window,Worker)]
interface PerformanceObserver {
  constructor(PerformanceObserverCallback callback);
  undefined observe (optional PerformanceObserverInit options = {});
  undefined disconnect ();
  PerformanceEntryList takeRecords();
  [SameObject] static readonly attribute FrozenArray<DOMString> supportedEntryTypes;
};
注意

为了将性能开销降到最低,应用程序应仅订阅感兴趣的事件类型,并在不再需要观察性能数据时断开观察者。 不支持按名称过滤,因为这将隐式地要求订阅所有事件类型——这是可能的,但不鼓励这样做,因为这会生成大量事件。

5.1 PerformanceObserverCallbackOptions 字典

WebIDLdictionary PerformanceObserverCallbackOptions {
  unsigned long long droppedEntriesCount;
};
droppedEntriesCount
一个整数,表示当 PerformanceObserver需要丢弃条目 设置时, 观察者正在观察的条目类型的丢弃条目数。

5.2 observe() 方法

observe() 方法指示用户代理注册 观察者并必须执行以下步骤:

  1. relevantGlobal 成为 this相关全局对象
  2. 如果 optionsentryTypestype 成员 都被省略,则 抛出一个 "TypeError"。
  3. 如果 optionsentryTypes 存在 且 任何其他 成员也存在,则 抛出一个 "TypeError"。
  4. 通过运行以下步骤来更新或检查 this观察者类型
    1. 如果 this观察者类型"undefined":
      1. 如果 optionsentryTypes 成员存在,则将 this观察者类型 设置为 "multiple"
      2. 如果 optionstype 成员 存在,则 将 this观察者类型 设置为 "single"
    2. 如果 this观察者类型"single"optionsentryTypes 成员存在,则 抛出一个 "InvalidModificationError"。
    3. 如果 this观察者类型"multiple"optionstype 成员 存在,则 抛出一个 "InvalidModificationError"。
  5. this需要丢弃条目 设置为 true。
  6. 如果 this观察者类型"multiple",请运行以下步骤:
    1. entry typesoptionsentryTypes 序列。
    2. entry types 中移除所有不包含在 relevantGlobal受支持条目类型的冻结数组 中的类型。用户代理 应该 通知 开发者 如果 entry types 被修改。例如,列出已移除类型的控制台 警告可能是合适的。
    3. 如果生成的 entry types 序列是空序列,则中止这些步骤。用户代理 应该 通知 开发者当步骤被中止时通知注册 已被中止。例如,控制台警告可能是 合适的。
    4. 如果 relevantGlobal已注册性能观察者对象列表 包含一个 已注册性能观察者,其 观察者this, 用包含 options 作为唯一项的列表替换其 选项列表
    5. 否则,创建并附加一个 已注册性能观察者 对象到 已注册性能 观察者对象列表relevantGlobal,其中 观察者 设置为 this,并将 选项列表 设置为 包含 options 作为唯一项的列表。
  7. 否则,运行以下步骤:
    1. 断言 this观察者类型"single"
    2. 如果 optionstype 不包含 在 relevantGlobal受支持条目类型的冻结数组 中,则中止这些步骤。用户代理 应该 通知 开发者当这种情况发生时,例如通过控制台警告。
    3. 如果 relevantGlobal已注册性能观察者对象列表 包含一个 已注册性能观察者 obs,其 观察者this
      1. 如果 obs选项列表 包含一个 PerformanceObserverInitcurrentOptionstype 等于 optionstype, 将 currentOptions 替换为 optionsobs选项列表 中。
      2. 否则,将 options 附加到 obs选项列表
    4. 否则,创建并附加一个 已注册性能观察者 对象到 已注册性能 观察者对象列表relevantGlobal,其中 观察者 设置为 this 并将 选项列表 设置 为包含 options 作为唯一项的列表。
    5. 如果 optionsbuffered 标志 被设置:
      1. tuple 成为 options相关性能条目元组relevantGlobal
      2. 对于 tuple 的每个 entry性能条目缓冲区 中:

        1. 如果 应添加条目 使用 entryoptions 作为 参数返回 true,附加 entry观察者缓冲区
      3. 排队 PerformanceObserver 任务relevantGlobal 作为输入。
注意

一个 PerformanceObserver 对象需要 始终调用 observe() 使用 optionsentryTypes 设置 或 始终 调用 observe() 使用 optionstype 设置。 如果一个 PerformanceObserver 调用 observe() 使用 entryTypes 并且还 调用了 observe 与 type,则会抛出异常。 这是为了避免混淆调用的堆叠方式。当 使用 entryTypes 时,不能使用 PerformanceObserverInit 中的其他参数。 此外, 多次 observe() 调用将被 覆盖 为了向后兼容 并且因为在这种情况下一个调用应该足够。另一方面, 使用 type 时,调用 将堆叠,因为单个调用只能指定一种类型。调用 observe() 使用重复的 type 也将被覆盖。

5.2.1 PerformanceObserverInit 字典

WebIDLdictionary PerformanceObserverInit {
  sequence<DOMString> entryTypes;
  DOMString type;
  boolean buffered;
};
entryTypes
要观察的条目类型列表。如果存在,该列表 不能 为空,并且不能包含其他成员。用户代理无法识别的类型 必须 被忽略。
type
要观察的单个条目类型。用户代理无法识别的类型 必须 被忽略。可以存在其他成员。
buffered
一个标志,表示是否应将缓冲条目排入观察者的缓冲区。

5.2.2 PerformanceObserverEntryList 接口

WebIDL[Exposed=(Window,Worker)]
interface PerformanceObserverEntryList {
  PerformanceEntryList getEntries();
  PerformanceEntryList getEntriesByType (DOMString type);
  PerformanceEntryList getEntriesByName (DOMString name, optional DOMString type);
};

每个 PerformanceObserverEntryList 对象都有一个相关的 条目列表, 其中包含一个 PerformanceEntryList,并在构造时初始化。

5.2.2.1 getEntries() 方法

返回一个 PerformanceEntryList 对象, 该对象是通过 按名称和类型过滤缓冲区 算法 获取的,其中 this条目列表 中的 nametype 均设置为 null

5.2.2.2 getEntriesByType() 方法

返回一个 PerformanceEntryList 对象, 通过 按名称和类型过滤缓冲区 算法返回, this条目列表 中, name 设置为 null,并且 type 设置为方法输入的 type 参数。

5.2.2.3 getEntriesByName() 方法

返回一个 PerformanceEntryList 对象, 通过 按名称和类型过滤缓冲区 算法返回, this条目列表 中, name 设置为方法输入的 name 参数, 如果省略了可选的 entryType,则 type 设置为 null, 否则设置为方法输入的 type 参数。

5.3 takeRecords() 方法

takeRecords() 方法必须 返回 此对象观察者缓冲区的副本,并清空 此对象观察者缓冲区

5.4 disconnect() 方法

disconnect() 方法必须执行以下操作:

  1. 此对象已注册性能观察者对象列表中移除。
  2. 清空 此对象观察者缓冲区
  3. 清空 此对象选项列表

5.5 supportedEntryTypes 属性

每个 全局对象 都有一个相关的 支持的条目类型的冻结数组, 该数组根据支持的条目类型,从 注册表 中按字母顺序排序后 通过 FrozenArray 创建。

当调用 supportedEntryTypes 属性的 getter 时,运行以下步骤:

  1. globalObject环境设置对象的全局对象
  2. 返回 globalObject支持的条目类型的冻结数组
注意

此属性允许 Web 开发者轻松了解用户代理支持的条目类型。

6. 处理

6.1 排队一个 PerformanceEntry

排队一个 PerformanceEntry (newEntry),请执行以下步骤:

  1. 如果 newEntryid 未设置:
    1. id 成为运行 生成 id 的结果,用于 newEntry
    2. newEntryid 设置为 id
  2. interested observers 为一个初始为空的集合,包含 PerformanceObserver 对象。
  3. entryType 设为 newEntryentryType 值。
  4. relevantGlobal 设为 newEntry相关全局对象
  5. 如果 relevantGlobal相关文档
    1. newEntrynavigationId 设置为 relevantGlobal相关文档最近的导航id
  6. 否则,将 newEntrynavigationId 设置为 null。
  7. 对于 relevantGlobal 的每个 注册的性能观察者 regObs:
    1. 如果 regObs选项列表 包含一个 PerformanceObserverInitoptions,其 entryTypes 成员包括 entryType,或者其 type 成员 等于 entryType

      1. 如果 应该添加条目 返回 true,则将 regObs观察者 添加到 interested observers
  8. 对于 interested observers 中的每个 observer:
    1. newEntry 添加到 observer观察者缓冲区
  9. tuple 设为 相关性能条目元组,包括 entryTyperelevantGlobal
  10. isBufferFull 设为运行 确定性能条目缓冲区是否已满 算法的结果,输入为 tuple
  11. shouldAdd 设为 是否应添加条目 算法的结果,输入为 newEntry
  12. 如果 isBufferFull 为 false 且 shouldAdd 为 true,则将 newEntry 附加tuple性能条目缓冲区
  13. 排队 PerformanceObserver 任务 ,输入为 relevantGlobal

6.2 排队一个导航 PerformanceEntry

排队一个导航 PerformanceEntry (newEntry),请执行以下步骤:

  1. id 成为运行 生成 id 的结果,用于 newEntry
  2. relevantGlobalnewEntry相关全局对象
  3. newEntryid 设置为 id
  4. newEntrynavigationId 设置为 id
  5. 如果 relevantGlobal相关文档
    1. relevantGlobal相关文档最近的导航 设置为 newEntry
  6. 使用 newEntry 作为输入,排队一个 PerformanceEntry

6.3 排队PerformanceObserver任务

在给定relevantGlobal作为输入的情况下,要求排队PerformanceObserver任务时,请执行以下步骤:

  1. 如果relevantGlobalperformance observer任务排队标志已设置,终止这些步骤。
  2. 设置relevantGlobalperformance observer任务排队标志
  3. 排队一个任务,包括执行以下子步骤。排队任务的任务源性能时间线任务源
    1. 取消设置relevantGlobalperformance observer任务排队标志
    2. notifyList成为relevantGlobal已注册的performance observer对象列表的副本。
    3. 对于notifyList中的每个已注册的performance observer对象registeredObserver,执行以下步骤:
      1. poregisteredObserverobserver
      2. entries成为po观察者缓冲区的副本。
      3. 如果entries为空,则返回。
      4. 清空po观察者缓冲区
      5. observerEntryList成为一个新的PerformanceObserverEntryList,其条目列表设置为entries
      6. droppedEntriesCount为空。
      7. 如果po需要丢弃条目已设置,则执行以下步骤:
        1. droppedEntriesCount设置为0。
        2. 对于registeredObserver选项列表中的每个PerformanceObserverInititem
          1. 对于itemtype或其entryTypes中出现的每个DOMString entryType
            1. maprelevantGlobal性能条目缓冲区映射
            2. tuple获取map中以entryType的条目的结果。
            3. droppedEntriesCount增加tuple丢弃条目计数
        3. po需要丢弃条目设置为false。
      8. callbackOptionsPerformanceObserverCallbackOptions,其droppedEntriesCount已设置为droppedEntriesCount(如果droppedEntriesCount不为空),否则未设置。
      9. 使用observerEntryList作为第一个参数,po作为第二个参数,并作为回调this值,以及callbackOptions作为第三个参数调用po观察者回调。如果这抛出异常,报告该异常

性能时间线任务队列是一个低优先级队列,如果可能,用户代理应在空闲时段处理此队列,以尽量减少性能监控代码的影响。

6.4 按名称和类型过滤缓冲区映射

当要求使用可选的nametype运行按名称和类型过滤缓冲区映射算法时,请执行以下步骤:

  1. result成为一个最初为空的列表
  2. map为与性能条目缓冲区映射关联的缓冲区,且此缓冲区关联的是this相关全局对象
  3. tuple list成为一个空的列表
  4. 如果type不为null,附加在map上通过type作为获取条目的值的结果到tuple list。否则,分配通过获取值map上的结果到tuple list
  5. 对于tuple list中的每个tuple,执行以下步骤:
    1. buffer成为tuple性能条目缓冲区
    2. 如果tuple从时间线可用为false,继续下一个tuple
    3. entries成为运行按名称和类型过滤缓冲区算法,使用buffernametype作为输入的结果。
    4. 对于entries中的每个entry附加entryresult
  6. 按时间顺序对results的条目进行排序,依据startTime
  7. 返回result

6.5 按名称和类型过滤缓冲区

当要求使用buffernametype作为输入运行按名称和类型过滤缓冲区算法时,请执行以下步骤:

  1. result成为一个最初为空的列表
  2. 对于buffer中的每个PerformanceEntry entry,执行以下步骤:
    1. 如果type不为null,且typeentryentryType属性不相同,则继续下一个entry
    2. 如果name不为null,且nameentryname属性不相同,则继续下一个entry
    3. 附加entryresult
  3. 按时间顺序对result中的条目进行排序,依据startTime
  4. 返回result

6.6 判断性能条目缓冲区是否已满

判断性能条目缓冲区是否已满,输入tuple,请执行以下步骤:

  1. num current entriestuple性能条目缓冲区的大小。
  2. 如果num current entries小于tuplemaxBufferSize,返回false。
  3. tuple丢弃的条目数增加1。
  4. 返回true。

6.7 生成性能条目id

当被要求为entry生成生成一个id时,执行以下步骤:

  1. relevantGlobalentry相关全局对象
  2. relevantGlobal上一个性能条目id增加一个由用户代理选择的小数。
  3. 返回relevantGlobal上一个性能条目id

用户代理可以选择每次增加一个小的随机整数作为last performance entry id。用户代理不得选择一个全局的随机整数,并将其应用于所有全局对象的last performance entry id,因为这可能会引入跨域泄漏。

注意

初始的last performance entry id值是随机的,用户代理会选择一个小数增加,而不是1,以防止开发者将其视为在Web应用程序中生成的条目数量的计数器。

7. 隐私注意事项

本规范扩展了由[HR-TIME-3]定义的Performance接口,并提供了从性能时间线中排队和检索条目的方法。有关暴露高分辨率时间信息的隐私注意事项,请参阅[HR-TIME-3]。每个引入新性能条目的新规范也应有其自己的隐私注意事项。

最后的性能条目ID故意初始化为随机值,并在每次新的PerformanceEntry被排队时通过另一个小值递增。用户代理可以选择对所有用户使用一致的递增值,也可以为每个全局对象选择不同的递增值,或者每次选择一个新的随机递增值。然而,为防止跨源泄露并确保不会因此启用指纹识别,用户代理不得仅仅选择一个唯一的随机整数,并将其作为所有PerformanceEntry对象在所有全局对象中的一致递增值。

8. 安全注意事项

本规范扩展了由[HR-TIME-3]定义的Performance接口,并提供了从性能时间线中排队和检索条目的方法。有关暴露高分辨率时间信息的安全注意事项,请参阅[HR-TIME-3]。每个引入新性能条目的新规范也应有其自己的安全注意事项。

9. 依赖项

[INFRA]规范定义了以下内容:获取条目的值

A. IDL 索引

WebIDLpartial interface Performance {
  PerformanceEntryList getEntries ();
  PerformanceEntryList getEntriesByType (DOMString type);
  PerformanceEntryList getEntriesByName (DOMString name, optional DOMString type);
};
typedef sequence<PerformanceEntry> PerformanceEntryList;

[Exposed=(Window,Worker)]
interface PerformanceEntry {
  readonly    attribute unsigned long long  id;
  readonly    attribute DOMString           name;
  readonly    attribute DOMString           entryType;
  readonly    attribute DOMHighResTimeStamp startTime;
  readonly    attribute DOMHighResTimeStamp duration;
  readonly    attribute unsigned long long  navigationId;
  [Default] object toJSON();
};

callback PerformanceObserverCallback = undefined (PerformanceObserverEntryList entries,
                                             PerformanceObserver observer,
                                             optional PerformanceObserverCallbackOptions options = {});
[Exposed=(Window,Worker)]
interface PerformanceObserver {
  constructor(PerformanceObserverCallback callback);
  undefined observe (optional PerformanceObserverInit options = {});
  undefined disconnect ();
  PerformanceEntryList takeRecords();
  [SameObject] static readonly attribute FrozenArray<DOMString> supportedEntryTypes;
};

dictionary PerformanceObserverCallbackOptions {
  unsigned long long droppedEntriesCount;
};

dictionary PerformanceObserverInit {
  sequence<DOMString> entryTypes;
  DOMString type;
  boolean buffered;
};

[Exposed=(Window,Worker)]
interface PerformanceObserverEntryList {
  PerformanceEntryList getEntries();
  PerformanceEntryList getEntriesByType (DOMString type);
  PerformanceEntryList getEntriesByName (DOMString name, optional DOMString type);
};

B. 致谢

感谢 Arvind Jain, Boris Zbarsky, Jatinder Mann, Nat Duca, Philippe Le Hegaret, Ryosuke Niwa, Shubhie Panicker, Todd Reifsteck, Yoav Weiss 和 Zhiheng Wang 对本工作的贡献。

C. 参考文献

C.1 规范性参考

[dom]
DOM Standard. Anne van Kesteren. WHATWG. 现行标准. URL: https://dom.spec.whatwg.org/
[HR-TIME-3]
High Resolution Time. Yoav Weiss. W3C. 2023年7月19日. W3C 工作草案. URL: https://www.w3.org/TR/hr-time-3/
[HTML]
HTML Standard. Anne van Kesteren; Domenic Denicola; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. 现行标准. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Infra Standard. Anne van Kesteren; Domenic Denicola. WHATWG. 现行标准. URL: https://infra.spec.whatwg.org/
[RFC2119]
RFC中表示要求级别的关键词. S. Bradner. IETF. 1997年3月. 最佳现行实践. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC8174]
RFC 2119关键词中的大写与小写歧义. B. Leiba. IETF. 2017年5月. 最佳现行实践. URL: https://www.rfc-editor.org/rfc/rfc8174
[WebIDL]
Web IDL 标准. Edgar Chen; Timothy Gu. WHATWG. 现行标准. URL: https://webidl.spec.whatwg.org/

C.2 参考性参考文献

[NAVIGATION-TIMING-2]
Navigation Timing Level 2. Yoav Weiss; Noam Rosenthal. W3C. 2024年2月1日. W3C工作草案. URL: https://www.w3.org/TR/navigation-timing-2/
[PERFORMANCE-TIMELINE]
Performance Timeline. Nicolas Pena Moreno. W3C. 2024年2月2日. W3C候选推荐标准. URL: https://www.w3.org/TR/performance-timeline/
[RESOURCE-TIMING-2]
Resource Timing. Yoav Weiss; Noam Rosenthal. W3C. 2022年10月4日. W3C候选推荐标准. URL: https://www.w3.org/TR/resource-timing-2/
[USER-TIMING-2]
User Timing Level 2. Ilya Grigorik. W3C. 2019年2月26日. W3C推荐标准. URL: https://www.w3.org/TR/user-timing-2/
[WORKERS]
Web Workers. Ian Hickson. W3C. 2021年1月28日. W3C工作组说明. URL: https://www.w3.org/TR/workers/