效能資料

Performance API 測量並公開可為您的 Web 應用程式收集的效能指標。它提供了觀察應用程式效能各個方面的方法。它不提供效能資料分析或視覺化。然而,Performance API 與瀏覽器中的開發者工具整合良好,其資料通常會發送到分析端點和庫,以記錄有助於您評估資料以找出影響使用者效能瓶頸的效能指標。

本頁面提供了關於存在哪些 Performance API 資料、如何收集這些資料以及如何訪問這些資料的概述。

收集資料

Performance API 公開的大多數指標都會由瀏覽器自動收集,您無需告訴它去收集:只需檢索即可。

某些指標確實需要您告訴瀏覽器要測量什麼

  • Element Timing 指標測量載入和渲染特定 DOM 元素所需的時間。此指標需要選擇加入:要要求瀏覽器包含特定元素的指標,您必須為其新增 elementtiming 屬性。
  • User Timing 指標使您能夠測量程式中任意兩點之間的時間,這些點可能對應於應用程式定義的事務(例如使用者登入)。要收集這些指標,您需要在相關點新增 Performance API 呼叫。
  • Server Timing 指標使您能夠測量應用程式定義的伺服器端事務所需的時間。要收集這些指標,您的伺服器必須傳送 Server-Timing HTTP 標頭。

效能資料結構

使用 Performance API,您可以在 WindowWorker 的全域性上下文中收集效能資料。如果您正在為多個上下文收集效能指標,請檢視 performance.timeOrigin 以同步不同上下文的時間起點。

在這些上下文中,單個性能資料由效能條目表示。

效能條目

單個記錄的效能資料點稱為*效能條目*,它由 PerformanceEntry 介面的例項表示。

Performance API 記錄各種不同型別的效能資料,而 PerformanceEntry 有一個 entryType 屬性,它是一個描述此效能條目型別的字串

  • "element" 記錄元素載入和渲染所需的時間。
  • "event" 記錄瀏覽器響應事件觸發器開始執行事件處理程式所需的時間,以及事件處理程式執行所需的時間。用於測量 下次繪製互動
  • "first-input" 記錄 首次輸入延遲
  • "largest-contentful-paint" 記錄頁面載入期間最大的繪製。
  • "layout-shift" 記錄每個動畫幀中頁面佈局移動了多少的度量。
  • "longtask" 記錄耗時 50 毫秒或更長的任務。
  • "mark" 記錄開發者建立的自定義時間戳。
  • "measure" 記錄開發者建立的兩個時間戳之間的自定義測量。
  • "navigation" 記錄與導航到頁面和頁面初始載入相關的指標。
  • "paint" 記錄頁面載入期間渲染的關鍵時刻。
  • "resource" 記錄瀏覽器獲取資源所需的時間。
  • "visibility-state" 記錄頁面可見狀態更改的時間,即選項卡從前臺切換到後臺或反之亦然。

效能條目子類

特定的條目型別通常包含額外的特定型別資料:例如,"resource" 型別捕獲 DNS 查詢開始和結束的時間。因此,條目由擴充套件基本 PerformanceEntry 介面的子類表示。例如,"resource" 條目由 PerformanceResourceTiming 介面的例項表示,該介面繼承自 PerformanceEntry,並添加了用於記錄 DNS 查詢時間戳的屬性。

PerformanceEntry 的子類也定義了 PerformanceEntry 本身屬性的語義:例如,PerformanceEntry 有一個 name 屬性,其含義取決於子類。

以下介面繼承自 PerformanceEntry

訪問資料

您可以透過兩種方式訪問效能條目。首選方式是使用 PerformanceObserver 介面,該介面使用一個回撥函式進行構造,當記錄特定效能條目時呼叫該函式。然後呼叫其 observe 方法,傳入要觀察的型別,並使用 buffered 選項來檢索在觀察之前發生的條目。

js
function logEventDuration(entries) {
  const events = entries.getEntriesByType("event");
  for (const event of events) {
    console.log(
      `Event handler took: ${
        event.processingEnd - event.processingStart
      } milliseconds`,
    );
  }
}

const observer = new PerformanceObserver(logEventDuration);
observer.observe({ type: "event", buffered: true });

或者,您可以使用 Performance.getEntries()Performance.getEntriesByName()Performance.getEntriesByType() 方法來檢索頁面上的所有效能條目,或者檢索與給定名稱或型別匹配的條目。

js
const events = performance.getEntriesByType("event");

for (const event of events) {
  console.log(
    `Event handler took: ${
      event.processingEnd - event.processingStart
    } milliseconds`,
  );
}

PerformanceObserver 選項更受青睞,因為

  • getEntries* 方法將始終返回自時間軸開始以來所有相關的條目,因此如果您呼叫它兩次,您將再次看到相同的條目,並且需要過濾掉您之前看到的條目。
  • 觀察者通知是非同步傳遞的,因此瀏覽器可以在空閒時間分派它們,以最大限度地減少其效能影響。
  • 並非所有條目型別都與 getEntries* 方法一起使用。對於某些條目,您必須使用效能觀察者來訪問它們。

管理緩衝區大小

每個全域性物件都有一個性能條目的緩衝區限制。它確保瀏覽器在持有效能資料時不會消耗無限記憶體。特別是當您的網站或應用程式獲取大量資源時(例如,在使用輪詢時),您可能需要檢視緩衝區的限制。

entryType 識別符號 介面 最大緩衝區條目數
"mark" PerformanceMark 無限
"measure" PerformanceMeasure 無限
"navigation" PerformanceNavigationTiming 無限
"resource" PerformanceResourceTiming 250(可調,見下文)
"longtask" PerformanceLongTaskTiming 200
"paint" PerformancePaintTiming 2(不會更多)
"element" PerformanceElementTiming 150
"event" PerformanceEventTiming 150
"first-input" PerformanceEventTiming 1(不會更多)
"layout-shift" LayoutShift 150
"largest-contentful-paint" LargestContentfulPaint 150
"visibility-state" VisibilityStateEntry 50

表 1. 緩衝區大小(來源)。

對於 "resource" 條目型別,請參閱 管理資源緩衝區大小,瞭解如何設定不同的緩衝區大小。

對於 "first-input""paint",限制是指標定義固有的。條目不會超過一個(或兩個)。

PerformanceObserver 的回撥函式包含一個可選的 droppedEntriesCount 引數,它告訴您由於緩衝區儲存已滿而丟失了多少條目。

js
function perfObserver(list, observer, droppedEntriesCount) {
  list.getEntries().forEach((entry) => {
    // do something with the entries
  });
  if (droppedEntriesCount > 0) {
    console.warn(
      `${droppedEntriesCount} entries were dropped because the buffer was full.`,
    );
  }
}
const observer = new PerformanceObserver(perfObserver);
observer.observe({ type: "resource", buffered: true });

另一個有用的方法是 PerformanceObserver.takeRecords(),它返回效能觀察者中儲存的效能條目列表,同時清空它。

JSON 資料

所有效能條目都提供了一個 toJSON() 序列化器,它返回條目的 JSON 表示形式。如果您想收集所有可用資料並將其儲存在某處,這會很有用。

js
const observer = new PerformanceObserver((list) => {
  list.getEntries().forEach((entry) => {
    console.log(entry.toJSON());
  });
});

observer.observe({ type: "event", buffered: true });

這將記錄一個類似如下的 JSON 物件

json
{
  "name": "dragover",
  "entryType": "event",
  "startTime": 67090751.599999905,
  "duration": 128,
  "processingStart": 67090751.70000005,
  "processingEnd": 67090751.900000095,
  "cancelable": true
}

要獲取條目的字串表示形式,您可以直接對任何 PerformanceEntry 物件使用 JSON.stringify(entry);它會自動呼叫條目的 toJSON() 方法。

另見