用户计时

用户计时是性能 API 的一部分,它允许您使用 高精度时间戳(作为浏览器性能时间轴的一部分)来测量应用程序的性能。 有两种类型的计时性能条目

什么是用户计时?

浏览器会向浏览器的性能时间轴提供某些信息(称为“性能条目”)。 例如,这包括 资源计时 API 提供的条目,这些条目确定获取像图像这样的资源所需的时间。

但是,浏览器无法确定您的应用程序中发生了什么。 例如,当用户单击按钮或在您的应用程序中执行特定任务时,没有高精度性能测量。 用户计时 API 是浏览器性能时间轴的扩展,可帮助您测量和记录特定于您的应用程序的性能数据。

与调用 Date.now()performance.now() 相比,使用此 API 的优势在于,您可以为标记命名,并且它与性能工具很好地集成。 浏览器的开发者工具可以在“性能”面板中显示性能标记,并且它还与其他性能 API(如 PerformanceObserver 对象)配合使用。

添加性能标记

作为开始测量应用程序功能性能的第一步,您需要在代码的重要位置添加命名性能标记。 理想情况下,您需要浏览代码库,确定关键路径和需要确保快速执行的重要任务。

performance.mark() 方法用于创建 PerformanceMark。 该方法接受一个参数,即标记的name,如以下示例所示。

js
// 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 元素。

js
performance.mark("login-started", {
  startTime: 12.5,
  detail: { htmlElement: myElement.id },
});

测量标记之间的持续时间

现在您已在应用程序中添加了标记,您可以测量它们之间的时间。

Performance.measure() 方法用于创建 PerformanceMeasure 对象。 它接受一个name参数,用于标识测量值,以及两个标记startend,它将在它们之间进行测量。 以下示例创建了一个"login-duration"测量值,并测量登录过程的开始和结束之间的时长。

然后,该对象具有一个duration属性,该属性将为您计算结束标记时间戳减去开始标记时间戳。 例如,您可以记录此值或将其发送到某些分析端点。

js
const loginMeasure = performance.measure(
  "login-duration",
  "login-started",
  "login-finished",
);

console.log(loginMeasure.duration);

Performance.measure() 方法也可以使用选项对象进行配置,因此您可以执行更高级的测量或使用detail属性提供其他信息。

例如,您可以使用 event.timestamp 属性(来自 click 事件)来准确了解用户何时单击登录,并将其测量到 UI 更新的时刻(此处为"login-finished"标记)。

js
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 对象。 性能观察器允许您被动地订阅性能标记和指标,并在它们发生时接收通知。

js
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() 方法获取所有性能条目。 您可以在需要时对其进行过滤。

js
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) 方法按类型过滤条目。

js
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) 方法允许您按名称获取特定标记或指标。

js
// Log all marks named "debug-marks"
const debugMarks = performance.getEntriesByName("debug-mark", "mark");
debugMarks.forEach((entry) => {
  console.log(`${entry.name}'s startTime: ${entry.startTime}`);
});

删除标记和指标

要清理所有性能标记或指标,或仅清理特定条目,可以使用以下方法

js
// 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");

另请参阅