用户计时
用户计时是性能 API 的一部分,它允许您使用 高精度时间戳(作为浏览器性能时间轴的一部分)来测量应用程序的性能。 有两种类型的计时性能条目
PerformanceMark
条目是您可以在应用程序中的任何位置命名和添加的标记。PerformanceMeasure
条目是两个标记之间的时间测量值。
什么是用户计时?
浏览器会向浏览器的性能时间轴提供某些信息(称为“性能条目”)。 例如,这包括 资源计时 API 提供的条目,这些条目确定获取像图像这样的资源所需的时间。
但是,浏览器无法确定您的应用程序中发生了什么。 例如,当用户单击按钮或在您的应用程序中执行特定任务时,没有高精度性能测量。 用户计时 API 是浏览器性能时间轴的扩展,可帮助您测量和记录特定于您的应用程序的性能数据。
与调用 Date.now()
或 performance.now()
相比,使用此 API 的优势在于,您可以为标记命名,并且它与性能工具很好地集成。 浏览器的开发者工具可以在“性能”面板中显示性能标记,并且它还与其他性能 API(如 PerformanceObserver
对象)配合使用。
添加性能标记
作为开始测量应用程序功能性能的第一步,您需要在代码的重要位置添加命名性能标记。 理想情况下,您需要浏览代码库,确定关键路径和需要确保快速执行的重要任务。
performance.mark()
方法用于创建 PerformanceMark
。 该方法接受一个参数,即标记的name
,如以下示例所示。
// Place at a location in the code that starts login
performance.mark("login-started");
// Place at a location in the code that finishes login
performance.mark("login-finished");
如果name
参数不足,则可以使用选项对象配置mark()
,您可以在detail
属性中放置其他信息,该属性可以是任何类型。 您也可以根据需要设置不同的startTime
。 在以下代码中,startTime
设置为12.5
,并使用detail
提供其他信息,例如使用的 HTML 元素。
performance.mark("login-started", {
startTime: 12.5,
detail: { htmlElement: myElement.id },
});
测量标记之间的持续时间
现在您已在应用程序中添加了标记,您可以测量它们之间的时间。
Performance.measure()
方法用于创建 PerformanceMeasure
对象。 它接受一个name
参数,用于标识测量值,以及两个标记start
和end
,它将在它们之间进行测量。 以下示例创建了一个"login-duration"
测量值,并测量登录过程的开始和结束之间的时长。
然后,该对象具有一个duration
属性,该属性将为您计算结束标记时间戳减去开始标记时间戳。 例如,您可以记录此值或将其发送到某些分析端点。
const loginMeasure = performance.measure(
"login-duration",
"login-started",
"login-finished",
);
console.log(loginMeasure.duration);
Performance.measure()
方法也可以使用选项对象进行配置,因此您可以执行更高级的测量或使用detail
属性提供其他信息。
例如,您可以使用 event.timestamp
属性(来自 click
事件)来准确了解用户何时单击登录,并将其测量到 UI 更新的时刻(此处为"login-finished"
标记)。
loginButton.addEventListener("click", (clickEvent) => {
fetch(loginURL).then((data) => {
renderLoggedInUser(data);
const marker = performance.mark("login-finished");
performance.measure("login-click", {
detail: { htmlElement: myElement.id },
start: clickEvent.timeStamp,
end: marker.startTime,
});
});
});
观察性能指标
接收自定义性能指标通知的首选方式是使用 PerformanceObserver
对象。 性能观察器允许您被动地订阅性能标记和指标,并在它们发生时接收通知。
function perfObserver(list, observer) {
list.getEntries().forEach((entry) => {
if (entry.entryType === "mark") {
console.log(`${entry.name}'s startTime: ${entry.startTime}`);
}
if (entry.entryType === "measure") {
console.log(`${entry.name}'s duration: ${entry.duration}`);
}
});
}
const observer = new PerformanceObserver(perfObserver);
observer.observe({ entryTypes: ["measure", "mark"] });
有关更多信息,请参阅 PerformanceObserver
。
检索标记和指标
浏览器性能时间轴中有许多不同的性能条目。 一些由浏览器添加,一些可能由您添加,例如上面的示例中的登录标记和指标。
要在某一时间点检索性能标记和指标,Performance
接口提供了三种方法,如下所示。
注意:以下方法不会向您通知新的性能标记;您将只获得在调用这些方法时已创建的标记。 有关使用 PerformanceObserver
接收有关新指标的通知(随着它们可用),请参阅上面的 观察性能指标 部分。 通常,使用性能观察器是获取性能标记和指标的首选方式。
performance.getEntries()
方法获取所有性能条目。 您可以在需要时对其进行过滤。
const entries = performance.getEntries();
entries.forEach((entry) => {
if (entry.entryType === "mark") {
console.log(`${entry.name}'s startTime: ${entry.startTime}`);
}
if (entry.entryType === "measure") {
console.log(`${entry.name}'s duration: ${entry.duration}`);
}
});
performance.getEntriesByType(entryType)
方法按类型过滤条目。
const marks = performance.getEntriesByType("mark");
marks.forEach((entry) => {
console.log(`${entry.name}'s startTime: ${entry.startTime}`);
});
const measures = performance.getEntriesByType("measure");
measures.forEach((entry) => {
console.log(`${entry.name}'s duration: ${entry.duration}`);
});
performance.getEntriesByName(name, entryType)
方法允许您按名称获取特定标记或指标。
// Log all marks named "debug-marks"
const debugMarks = performance.getEntriesByName("debug-mark", "mark");
debugMarks.forEach((entry) => {
console.log(`${entry.name}'s startTime: ${entry.startTime}`);
});
删除标记和指标
要清理所有性能标记或指标,或仅清理特定条目,可以使用以下方法
// Clear all marks
performance.clearMarks();
// Removes the marker with the name "myMarker"
performance.clearMarks("myMarker");
// Clear all measures
performance.clearMeasures();
// Removes the measure with the name "myMeasure"
performance.clearMeasures("myMeasure");