Copyright © 2026 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
この仕様は、Web 開発者が高精度のタイムスタンプにアクセスできるようにすることで、アプリケーションのパフォーマンスを測定するのに役立つインターフェイスを定義します。
この節は、公開時点におけるこの 文書のステータスを説明するものです。現在の W3C 公開物と、この技術報告書の最新リビジョンの一覧は、 W3C 標準および草案 インデックスで確認できます。
この User Timing 仕様は、[USER-TIMING-2] を置き換えることを意図しており、以下を含みます:
この文書は、Web Performance Working Group により、 Recommendation track を用いた Candidate Recommendation Draft として公開されました。
Candidate Recommendation としての公開は、 W3C およびそのメンバーによる承認を意味するものではありません。Candidate Recommendation Draft は、ワーキンググループが後続の Candidate Recommendation Snapshot に含めることを意図している、 以前の Candidate Recommendation からの変更を統合します。
これは草案文書であり、いつでも他の文書によって更新、置換、または廃止される可能性があります。 作業中の文書以外のものとしてこの文書を引用することは不適切です。
この文書は、 W3C Patent Policy の下で運営されているグループによって作成されました。 W3C は、 そのグループの成果物に関連して行われた 特許開示の公開一覧 を維持しています。そのページには、特許を開示するための 手順も含まれています。ある個人が、 Essential Claim(s) を含むとその個人が考える特許について実際の知識を有している場合、その情報を W3C Patent Policy の第 6 節に従って開示しなければなりません。
この文書は、 2025年8月18日版 W3C Process Document によって管理されます。
本节是非规范性的。
Web 开发者需要能够评估和理解其
应用程序的性能特征。虽然 JavaScript [ECMA-262] 提供了一种测量
应用程序延迟的机制(从 Date.now() 方法取得当前时间戳),但该
时间戳的精度会因用户代理而异。
本文档定义了 PerformanceMark 和 PerformanceMeasure 接口,以及对
Performance 接口的扩展,它们公开高
精度、单调递增的时间戳,使开发者能够更好地测量其应用程序的性能
特征。
下面的脚本展示了开发者如何使用本文档定义的接口来获得 与开发者脚本相关的计时数据。
async function run() {
performance.mark("startTask1");
await doTask1(); // 一些开发者代码
performance.mark("endTask1");
performance.mark("startTask2");
await doTask2(); // 一些开发者代码
performance.mark("endTask2");
// 将它们记录出来
const entries = performance.getEntriesByType("mark");
for (const entry of entries) {
console.table(entry.toJSON());
}
}
run();
[PERFORMANCE-TIMELINE-2] 定义了两种
可用于检索已记录指标的机制:getEntries()
和 getEntriesByType() 方法,以及
PerformanceObserver 接口。前者最适合
你想要在某个单一时间点按名称检索特定指标的场景,
后者则针对你可能希望在新指标变得
可用时接收通知的场景进行了优化。
再举一个例子,假设有一个元素,当它被 点击时,会获取一些新内容并指示该内容已获取完成。 我们想要报告从用户点击到获取 完成之间的时间。我们不能标记点击处理程序执行的时间,因为那样 会漏掉处理事件的延迟,所以我们改用事件的 硬件时间戳。我们还想知道组件名称,以便获得 更详细的分析数据。
element.addEventListener("click", e => {
const component = getComponent(element);
fetch(component.url).then(() => {
element.textContent = "Updated";
const updateMark = performance.mark("update_component", {
detail: {component: component.name},
});
performance.measure("click_to_update_component", {
detail: {component: component.name},
start: e.timeStamp,
end: updateMark.startTime,
});
});
});
除标记为非规范性的章节外,本规范中的所有编写指南、图示、示例和注释都是 非规范性的。本规范中的其他所有内容都是规范性的。
本文档中的关键词 MAY 和 MUST 在且仅在它们如这里所示以全大写形式出现时, 应按 BCP 14 [RFC2119] [RFC8174] 中所描述的方式解释。
某些一致性要求以对属性、 方法或对象的要求来表述。这些要求应解释为 对用户代理的要求。
本规范中的 IDL 片段 MUST 按 Web IDL 规范中关于一致性 IDL 片段的描述来解释。 [WEBIDL]
Performance
接口的扩展
Performance 接口和
DOMHighResTimeStamp
定义于 [HR-TIME-2]。
PerformanceEntry
接口定义于 [PERFORMANCE-TIMELINE-2]。
WebIDLdictionary PerformanceMarkOptions {
any detail;
DOMHighResTimeStamp startTime;
};
dictionary PerformanceMeasureOptions {
any detail;
(DOMString or DOMHighResTimeStamp) start;
DOMHighResTimeStamp duration;
(DOMString or DOMHighResTimeStamp) end;
};
partial interface Performance {
PerformanceMark mark(DOMString markName, optional PerformanceMarkOptions markOptions = {});
undefined clearMarks(optional DOMString markName);
PerformanceMeasure measure(DOMString measureName, optional (DOMString or PerformanceMeasureOptions) startOrMeasureOptions = {}, optional DOMString endMark);
undefined clearMeasures(optional DOMString measureName);
};
存储带有关联名称的时间戳(一个“mark”)。它 MUST 运行这些 步骤:
detailstartTime移除带有关联名称的已存储时间戳。它 MUST 运行这些 步骤:
PerformanceMark
对象中移除所有位于 performance
entry buffer 中的对象。PerformanceMark 对象中列在 performance
entry buffer 中且其 name 是 markName 的所有对象。存储两个标记之间的 DOMHighResTimeStamp
持续时间,并附带关联名称(一个“measure”)。它 MUST 运行这些步骤:
PerformanceMeasureOptions
对象,并且 start、end、duration 和 detail 中至少有一个 存在,则运行以下
检查:
PerformanceMeasureOptions
对象,并且如果其 end 成员 存在,
则令 end time 为传入 startOrMeasureOptions 的 end 运行 convert a mark to a timestamp
算法所返回的值。PerformanceMeasureOptions
对象,并且如果其 start 和 duration
成员都 存在:
start
运行 convert a mark to a
timestamp 算法所返回的值。
duration
运行 convert a mark to a
timestamp 算法所返回的值。
Performance 对象的 now()
方法将会返回的值。
PerformanceMeasureOptions
对象,并且如果其 start 成员 存在,
则令 start time 为传入 startOrMeasureOptions 的 start 运行 convert a mark to a timestamp
算法所返回的值。PerformanceMeasureOptions
对象,并且如果其 duration 和
end 成员都
存在:
duration
运行 convert a mark to a
timestamp 算法所返回的值。
end 运行 convert a mark to a
timestamp 算法所返回的值。DOMString,则令
start time 为传入 startOrMeasureOptions 运行 convert a mark to a timestamp
算法所返回的值。
0。PerformanceMeasure 对象
(entry)。name 属性设置为 measureName。entryType 属性设置为 DOMString "measure"。
startTime 属性设置为 start time。duration 属性设置为从 start
time 到 end time 的持续时间。所得持续时间值 MAY
为负数。detail 属性:
PerformanceMeasureOptions
对象,并且 startOrMeasureOptions 的 detail 成员
存在:
detail
调用 StructuredSerialize
算法的结果。
detail 设置为
以 record 和 当前
realm 调用 StructuredDeserialize
算法的结果。null。detailstartdurationend移除带有关联名称的已存储时间戳。它 MUST 运行这些步骤:
PerformanceMeasure 对象中位于 performance
entry buffer 中的所有对象。PerformanceMeasure 对象中列在
performance
entry buffer 中且其 name 是 measureName 的所有对象。
PerformanceMark 接口还会将通过 Performance 接口的 mark() 方法创建的标记暴露给 Performance
Timeline。
WebIDL[Exposed=(Window,Worker)]
interface PerformanceMark : PerformanceEntry {
constructor(DOMString markName, optional PerformanceMarkOptions markOptions = {});
readonly attribute any detail;
};
PerformanceMark 接口扩展了 PerformanceEntry
接口的以下属性:
name 属性必须返回该标记的名称。
entryType 属性必须返回 DOMString "mark"。
startTime 属性必须返回一个 DOMHighResTimeStamp,
其值为该标记的时间值。
duration 属性必须返回值为 0 的 DOMHighResTimeStamp
。
PerformanceMark 接口包含以下
附加属性:
detail
属性必须返回其被设置为的值(它是从 PerformanceMarkOptions 字典复制而来的)。
PerformanceMark 构造器
PerformanceMark 构造器必须运行 以下步骤:
Window 对象,并且 markName 使用了与
PerformanceTiming
接口中的某个只读属性相同的名称,
则抛出一个 SyntaxError。
PerformanceMark 对象
(entry)。
name 属性设置为 markName。entryType 属性设置为 DOMString "mark"。startTime 属性:
duration 属性设置为 0。detail 为 null,则将
entry 的 detail 设置为
null。
detail 调用 StructuredSerialize
算法的结果。detail 设置为
以 record 和 当前
realm 调用 StructuredDeserialize
算法的结果。PerformanceMeasure 接口还会将
通过 Performance 接口的 measure() 方法创建的度量暴露给 Performance Timeline。
WebIDL[Exposed=(Window,Worker)]
interface PerformanceMeasure : PerformanceEntry {
readonly attribute any detail;
};
PerformanceMeasure 接口扩展了
PerformanceEntry
接口的以下属性:
name 属性必须返回该度量的名称。
entryType 属性必须返回 DOMString
"measure"。
startTime 属性必须返回一个 DOMHighResTimeStamp,
其值为该度量的开始标记。
duration 属性必须返回一个 DOMHighResTimeStamp,
其值为该度量的持续时间。
PerformanceMeasure 接口包含
以下附加属性:
detail 属性必须返回其被设置为的值(它是
从 PerformanceMeasureOptions 字典复制而来的)。
实现 User Timing API 的用户代理需要在
supportedEntryTypes 中包含 "mark" 和
"measure"。这允许开发者检测对 User Timing 的支持。
要将标记转换为时间戳,给定一个作为
DOMString 或 DOMHighResTimeStamp
的 mark,运行这些步骤:
DOMString,并且它与
PerformanceTiming
接口中的某个只读属性同名,则令 end time 为在
name 设置为 mark 的值时运行 convert a name to a timestamp 算法
所返回的值。
DOMString,则令 end time 为
performance
entry buffer 中其 name 是 mark 的 PerformanceMark 对象的最近一次出现中的
startTime 属性值。如果未找到匹配项,则抛出一个 SyntaxError。
DOMHighResTimeStamp:
TypeError。
要将名称转换为 时间戳,
给定一个作为
PerformanceTiming
接口中的只读
属性的 name,运行这些步骤:
Window 对象,则抛出一个 TypeError。navigationStart,则返回 0。PerformanceTiming
接口中 navigationStart 的值。
PerformanceTiming
接口中 name 的值。
0,则抛出一个
InvalidAccessError。
PerformanceTiming 接口定义于 [NAVIGATION-TIMING],并且 现在被视为已废弃。支持使用来自 PerformanceTiming 接口的名称,是为了保持向后兼容,但未来没有计划将此 功能扩展到 [NAVIGATION-TIMING-2] 中定义的 PerformanceNavigationTiming 接口(或其他接口)中的名称。
鼓励开发者使用以下推荐的标记名称来 标记常见计时。用户 代理不会验证这些名称的使用是否 适当或是否与其描述一致。
添加此类推荐的标记名称可以帮助性能 工具为站点定制指导。这些标记名称还可以帮助真实用户 监控提供商和用户代理大规模收集有关其应用程序性能的 Web 开发者信号,并在不需要任何站点特定工作的情况下将此信息呈现给 开发者。
在此示例中,页面在加载时异步初始化聊天小部件、 搜索框和新闻源。完成后, "mark_fully_loaded" 标记名称使实验室工具 和分析 提供商能够自动显示该计时。
window.addEventListener("load", (event) => {
Promise.all([
loadChatWidget(),
initializeSearchAutocomplete(),
initializeNewsfeed()]).then(() => {
performance.mark('mark_fully_loaded');
});
});
detail
元数据可以包含关于该功能的任何有用信息,包括:
在此示例中,FancyJavaScriptFramework 的 ImageOptimizationComponent 用于按最佳性能调整图像大小。代码记录 此功能的使用情况,以便实验室工具和分析能够衡量 它是否帮助提升了性能。
performance.mark('mark_feature_usage', {
'detail': {
'feature': 'ImageOptimizationComponent',
'framework': 'FancyJavaScriptFramework'
}
})
本节是非规范性的。
本规范定义的接口会暴露页面中特定 JavaScript 活动的、可能 敏感的计时信息。有关暴露 高分辨率计时信息的隐私和安全注意事项,请参见 [HR-TIME-2]。
由于 Web 平台的设计遵循这样一个不变原则:页面中包含的任何 脚本都与同一页面中包含的任何其他脚本具有相同的访问权限, 无论这些脚本的源如何, 本规范定义的接口不会对 已记录计时信息的记录或检索施加任何限制——也就是说,页面中包含的任何脚本记录的 user timing mark 或 measure,都可以被 同一页面上运行的任何其他脚本读取,而不论其源如何。
感谢 James Simonsen、 Jason Weber、 Nic Jansma、 Philippe Le Hegaret、 Karen Anderson、 Steve Souders、 Sigbjorn Vik、 Todd Reifsteck 和 Tony Gentilcore 对此工作的贡献。
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: