效能測量 API#

穩定性:2 - 穩定

原始碼: lib/perf_hooks.js

此模組提供 W3C Web 效能 API 子集的實作,以及 Node.js 特定效能測量額外的 API。

Node.js 支援下列 Web 效能 API

const { PerformanceObserver, performance } = require('node:perf_hooks');

const obs = new PerformanceObserver((items) => {
  console.log(items.getEntries()[0].duration);
  performance.clearMarks();
});
obs.observe({ type: 'measure' });
performance.measure('Start to Now');

performance.mark('A');
doSomeLongRunningProcess(() => {
  performance.measure('A to Now', 'A');

  performance.mark('B');
  performance.measure('A to B', 'A', 'B');
}); 

perf_hooks.performance#

一個物件,可用於從目前的 Node.js 實例收集效能指標。它類似於瀏覽器中的 window.performance

performance.clearMarks([name])#

如果未提供 name,則從效能時間軸中移除所有 PerformanceMark 物件。如果提供了 name,則僅移除已命名的標記。

performance.clearMeasures([name])#

如果未提供 name,則會從效能時序中移除所有 PerformanceMeasure 物件。如果已提供 name,則只會移除已命名的測量。

performance.clearResourceTimings([name])#

如果未提供 name,則會從資源時序中移除所有 PerformanceResourceTiming 物件。如果已提供 name,則只會移除已命名的資源。

performance.eventLoopUtilization([utilization1[, utilization2]])#

eventLoopUtilization() 方法傳回一個物件,其中包含事件迴圈處於閒置和活動狀態的累計持續時間,以高解析度毫秒計時器為單位。utilization 值為計算出的事件迴圈使用率 (ELU)。

如果主執行緒尚未完成引導,屬性值為 0。ELU 會立即在 工作執行緒 上提供,因為引導會在事件迴圈內發生。

utilization1utilization2 都是選用參數。

如果傳遞 utilization1,則會計算當前呼叫的 activeidle 時間之間的差值,以及對應的 utilization 值,並傳回 (類似於 process.hrtime())。

如果傳遞 utilization1utilization2,則會計算兩個參數之間的差值。這是一個方便的選項,因為與 process.hrtime() 不同,計算 ELU 比單一減法更複雜。

ELU 類似於 CPU 使用率,但它只會衡量事件迴圈統計資料,而不是 CPU 使用量。它表示事件迴圈在事件迴圈事件提供者 (例如 epoll_wait) 之外所花費的時間百分比。不會考慮其他 CPU 空閒時間。以下範例說明了大多數空閒程序如何擁有高 ELU。

'use strict';
const { eventLoopUtilization } = require('node:perf_hooks').performance;
const { spawnSync } = require('node:child_process');

setImmediate(() => {
  const elu = eventLoopUtilization();
  spawnSync('sleep', ['5']);
  console.log(eventLoopUtilization(elu).utilization);
}); 

雖然在執行此腳本時 CPU 大多處於空閒狀態,但 utilization 的值為 1。這是因為呼叫 child_process.spawnSync() 會阻止事件迴圈繼續進行。

傳遞使用者定義的物件,而不是先前呼叫 eventLoopUtilization() 的結果,將導致未定義的行為。無法保證傳回值反映事件迴圈的任何正確狀態。

performance.getEntries()#

傳回一個 `PerformanceEntry` 物件清單,依據 `performanceEntry.startTime` 的時間順序排列。如果您只對特定類型或名稱的效能條目感興趣,請參閱 `performance.getEntriesByType()` 和 `performance.getEntriesByName()`。

performance.getEntriesByName(name[, type])#

傳回一個 `PerformanceEntry` 物件清單,依據 `performanceEntry.startTime` 的時間順序排列,其 `performanceEntry.name` 等於 `name`,且(可選擇)其 `performanceEntry.entryType` 等於 `type`。

performance.getEntriesByType(type)#

傳回一個 `PerformanceEntry` 物件清單,依據 `performanceEntry.startTime` 的時間順序排列,其 `performanceEntry.entryType` 等於 `type`。

performance.mark(name[, options])#

  • name <字串>
  • options <物件>
    • detail <任何> 要包含在標記中的其他選用詳細資料。
    • startTime <數字> 一個選用的時間戳記,用作標記時間。預設值:`performance.now()`。

在效能時序中建立新的 PerformanceMark 項目。PerformanceMarkPerformanceEntry 的子類別,其 performanceEntry.entryType 永遠是 'mark',而 performanceEntry.duration 永遠是 0。效能標記用於標記效能時序中特定的重要時刻。

建立的 PerformanceMark 項目會放入全域效能時序,並可以使用 performance.getEntriesperformance.getEntriesByNameperformance.getEntriesByType 查詢。執行觀察時,應使用 performance.clearMarks 手動從全域效能時序清除項目。

performance.markResourceTiming(timingInfo, requestedUrl, initiatorType, global, cacheMode)#

此屬性是 Node.js 的擴充功能。在 Web 瀏覽器中無法使用。

在資源時序中建立新的 PerformanceResourceTiming 項目。PerformanceResourceTimingPerformanceEntry 的子類別,其 performanceEntry.entryType 永遠是 'resource'。效能資源用於標記資源時序中的時刻。

已建立的 PerformanceMark 項目會放入全域資源時間軸,並可以使用 performance.getEntriesperformance.getEntriesByNameperformance.getEntriesByType 查詢。執行觀察時,應使用 performance.clearResourceTimings 手動從全域效能時間軸中清除項目。

performance.measure(name[, startMarkOrOptions[, endMark]])#

  • name <字串>
  • startMarkOrOptions <字串> | <物件> 選用。
    • detail <任意> 要包含在測量中的其他選用詳細資料。
    • duration <數字> 起始時間和結束時間之間的持續時間。
    • end <數字> | <字串> 要用作結束時間的時間戳記,或用於識別先前記錄標記的字串。
    • start <數字> | <字串> 要用作起始時間的時間戳記,或用於識別先前記錄標記的字串。
  • endMark <字串> 選擇性。如果 startMarkOrOptions<物件>,則必須省略。

在效能時間軸中建立新的 PerformanceMeasure 項目。PerformanceMeasurePerformanceEntry 的子類別,其 performanceEntry.entryType 永遠是 'measure',而其 performanceEntry.duration 則測量自 startMarkendMark 以來經過的毫秒數。

startMark 參數可以識別效能時間軸中任何現有的 PerformanceMark,或可能識別 PerformanceNodeTiming 類別提供的任何時間戳記屬性。如果指定的 startMark 不存在,則會擲回錯誤。

選擇性的 endMark 參數必須識別效能時間軸中任何現有的 PerformanceMarkPerformanceNodeTiming 類別提供的任何時間戳記屬性。如果未傳遞任何參數,則 endMark 會是 performance.now(),否則如果指定的 endMark 不存在,則會擲回錯誤。

建立的 PerformanceMeasure 項目會放入全域效能時間軸中,並可以使用 performance.getEntriesperformance.getEntriesByNameperformance.getEntriesByType 查詢。執行觀察時,應該使用 performance.clearMeasures 手動從全域效能時間軸中清除項目。

performance.nodeTiming#

此屬性是 Node.js 的擴充功能。在 Web 瀏覽器中無法使用。

PerformanceNodeTiming 類別的執行個體,提供特定 Node.js 作業里程碑的效能指標。

performance.now()#

傳回目前的高解析度毫秒時間戳記,其中 0 代表目前 node 程序的開始時間。

performance.setResourceTimingBufferSize(maxSize)#

將效能資源計時緩衝區大小設定為指定的「資源」類型效能輸入物件數目。

預設最大緩衝區大小設定為 250。

performance.timeOrigin#

timeOrigin 指定目前 node 程序開始時的高解析度毫秒時間戳記,以 Unix 時間衡量。

performance.timerify(fn[, options])#

此屬性是 Node.js 的擴充功能。在 Web 瀏覽器中無法使用。

將函數包裝在一個新函數中,用來衡量包裝函數的執行時間。必須向 'function' 事件類型訂閱 PerformanceObserver,才能存取計時詳細資料。

const {
  performance,
  PerformanceObserver,
} = require('node:perf_hooks');

function someFunction() {
  console.log('hello world');
}

const wrapped = performance.timerify(someFunction);

const obs = new PerformanceObserver((list) => {
  console.log(list.getEntries()[0].duration);

  performance.clearMarks();
  performance.clearMeasures();
  obs.disconnect();
});
obs.observe({ entryTypes: ['function'] });

// A performance timeline entry will be created
wrapped(); 

如果封裝函式回傳承諾,將會附加一個 finally 處理函式到承諾,並且在 finally 處理函式被呼叫後回報持續時間。

performance.toJSON()#

一個物件,是 performance 物件的 JSON 表示。它類似於瀏覽器中的 window.performance.toJSON

事件:'resourcetimingbufferfull'#

當效能資源計時全球緩衝區已滿時,會觸發 'resourcetimingbufferfull' 事件。在事件監聽器中使用 performance.setResourceTimingBufferSize() 調整資源計時緩衝區大小,或使用 performance.clearResourceTimings() 清除緩衝區,以允許將更多項目新增至效能時間軸緩衝區。

類別:PerformanceEntry#

此類別的建構函式不會直接公開給使用者。

performanceEntry.duration#

此項目的總經過毫秒數。此值並非對所有效能項目類型都有意義。

performanceEntry.entryType#

效能項目的類型。它可能是下列其中一個

  • 'node'(僅限 Node.js)
  • 'mark'(在網路上可用)
  • 'measure'(適用於網路)
  • 'gc'(僅限 Node.js)
  • 'function'(僅限 Node.js)
  • 'http2'(僅限 Node.js)
  • 'http'(僅限 Node.js)

performanceEntry.name#

效能條目的名稱。

performanceEntry.startTime#

標示效能條目開始時間的高解析度毫秒時間戳記。

類別:PerformanceMark#

顯示透過 Performance.mark() 方法建立的標記。

performanceMark.detail#

使用 Performance.mark() 方法建立時指定的其他詳細資訊。

類別:PerformanceMeasure#

顯示透過 Performance.measure() 方法建立的測量。

此類別的建構函式不會直接公開給使用者。

performanceMeasure.detail#

使用 Performance.measure() 方法建立時指定的其他詳細資訊。

類別:PerformanceNodeEntry#

這個類別是 Node.js 的延伸。它不適用於網路瀏覽器。

提供詳細的 Node.js 計時資料。

此類別的建構函式不會直接公開給使用者。

performanceNodeEntry.detail#

特定於 entryType 的其他詳細資訊。

performanceNodeEntry.flags#

穩定性:0 - 已棄用:改用 performanceNodeEntry.detail

performanceEntry.entryType 等於 'gc' 時,performance.flags 屬性包含有關垃圾回收操作的其他資訊。其值可能為下列其中之一

  • perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_NO
  • perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_CONSTRUCT_RETAINED
  • perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_FORCED
  • perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_SYNCHRONOUS_PHANTOM_PROCESSING
  • perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_ALL_AVAILABLE_GARBAGE
  • perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_ALL_EXTERNAL_MEMORY
  • perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_SCHEDULE_IDLE

performanceNodeEntry.kind#

穩定性:0 - 已棄用:改用 performanceNodeEntry.detail

performanceEntry.entryType 等於 'gc' 時,performance.kind 屬性識別發生的垃圾回收操作類型。其值可能為下列其中之一

  • perf_hooks.constants.NODE_PERFORMANCE_GC_MAJOR
  • perf_hooks.constants.NODE_PERFORMANCE_GC_MINOR
  • perf_hooks.constants.NODE_PERFORMANCE_GC_INCREMENTAL
  • perf_hooks.constants.NODE_PERFORMANCE_GC_WEAKCB

垃圾回收 ('gc') 詳細資訊#

performanceEntry.type 等於 'gc' 時,performanceNodeEntry.detail 屬性將會是具有兩個屬性的 <Object>

  • kind <number> 其中之一
    • perf_hooks.constants.NODE_PERFORMANCE_GC_MAJOR
    • perf_hooks.constants.NODE_PERFORMANCE_GC_MINOR
    • perf_hooks.constants.NODE_PERFORMANCE_GC_INCREMENTAL
    • perf_hooks.constants.NODE_PERFORMANCE_GC_WEAKCB
  • flags <number> 其中之一
    • perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_NO
    • perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_CONSTRUCT_RETAINED
    • perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_FORCED
    • perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_SYNCHRONOUS_PHANTOM_PROCESSING
    • perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_ALL_AVAILABLE_GARBAGE
    • perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_ALL_EXTERNAL_MEMORY
    • perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_SCHEDULE_IDLE

HTTP ('http') 詳細資訊#

performanceEntry.type 等於 'http' 時,performanceNodeEntry.detail 屬性會是一個 <Object>,其中包含其他資訊。

如果 performanceEntry.name 等於 HttpClientdetail 會包含下列屬性:reqres。而 req 屬性會是一個 <Object>,其中包含 methodurlheadersres 屬性會是一個 <Object>,其中包含 statusCodestatusMessageheaders

如果 performanceEntry.name 等於 HttpRequestdetail 會包含下列屬性:reqres。而 req 屬性會是一個 <Object>,其中包含 methodurlheadersres 屬性會是一個 <Object>,其中包含 statusCodestatusMessageheaders

這可能會增加額外的記憶體負擔,而且應該只用於診斷目的,預設情況下不要在生產環境中啟用。

HTTP/2 ('http2') 詳細資料#

performanceEntry.type 等於 'http2' 時,performanceNodeEntry.detail 屬性會是一個 <Object>,其中包含其他效能資訊。

如果 performanceEntry.name 等於 Http2Streamdetail 會包含下列屬性

  • bytesRead <number> 接收的 DATA 框架位元組數目,針對這個 Http2Stream
  • bytesWritten <number> 傳送的 DATA 框架位元組數目,針對這個 Http2Stream
  • id <數字> 關聯的 Http2Stream 的識別碼
  • timeToFirstByte <數字> PerformanceEntry startTime 和接收第一個 DATA 幀之間經過的毫秒數。
  • timeToFirstByteSent <數字> PerformanceEntry startTime 和發送第一個 DATA 幀之間經過的毫秒數。
  • timeToFirstHeader <數字> PerformanceEntry startTime 和接收第一個標頭之間經過的毫秒數。

如果 performanceEntry.name 等於 Http2Session,則 detail 將包含下列屬性

  • bytesRead <數字> 接收的這個 Http2Session 的位元組數。
  • bytesWritten <數字> 發送的這個 Http2Session 的位元組數。
  • framesReceived <數字> Http2Session 接收的 HTTP/2 幀數。
  • framesSent <數字> Http2Session 發送的 HTTP/2 幀數。
  • maxConcurrentStreams <數字> Http2Session 生命週期中同時開啟的最大串流數。
  • pingRTT <數字> 傳送 PING 幀和接收其確認之間經過的毫秒數。僅在 Http2Session 上已傳送 PING 幀時才會出現。
  • streamAverageDuration <數字> 所有 Http2Stream 實例的平均持續時間(以毫秒為單位)。
  • streamCount <number>Http2Session 處理的 Http2Stream 執行個體數量。
  • type <string> 'server''client',用於識別 Http2Session 的類型。

Timerify(「函式」)詳細資料#

performanceEntry.type 等於 'function' 時,performanceNodeEntry.detail 屬性會是一個 <Array>,列出計時函式的輸入引數。

Net(「net」)詳細資料#

performanceEntry.type 等於 'net' 時,performanceNodeEntry.detail 屬性會是一個 <Object>,包含其他資訊。

如果 performanceEntry.name 等於 connectdetail 會包含下列屬性:hostport

DNS(「dns」)詳細資料#

performanceEntry.type 等於 'dns' 時,performanceNodeEntry.detail 屬性會是一個 <Object>,包含其他資訊。

如果 performanceEntry.name 等於 lookupdetail 會包含下列屬性:hostnamefamilyhintsverbatimaddresses

如果 performanceEntry.name 等於 lookupServicedetail 會包含下列屬性:hostporthostnameservice

如果 performanceEntry.name 等於 queryxxxgetHostByAddrdetail 會包含下列屬性:hostttlresultresult 的值與 queryxxxgetHostByAddr 的結果相同。

類別:PerformanceNodeTiming#

此屬性是 Node.js 的擴充功能。在 Web 瀏覽器中無法使用。

提供 Node.js 本身的計時詳細資料。此類別的建構函式未公開給使用者。

performanceNodeTiming.bootstrapComplete#

Node.js 程序完成引導的毫秒時間戳記。如果引導尚未完成,該屬性的值為 -1。

performanceNodeTiming.environment#

初始化 Node.js 環境的毫秒時間戳記。

performanceNodeTiming.idleTime#

事件迴圈在事件迴圈的事件提供者(例如:epoll_wait)中閒置的時間量的高解析度毫秒時間戳記。這不考慮 CPU 使用率。如果事件迴圈尚未啟動(例如,在主腳本的第一個刻度),則屬性的值為 0。

performanceNodeTiming.loopExit#

Node.js 事件迴圈退出的毫秒時間戳記。如果事件迴圈尚未退出,則屬性的值為 -1。它只能在 'exit' 事件的處理常式中具有非 -1 的值。

performanceNodeTiming.loopStart#

Node.js 事件迴圈啟動的毫秒時間戳記。如果事件迴圈尚未啟動(例如,在主腳本的第一個刻度),則屬性的值為 -1。

performanceNodeTiming.nodeStart#

Node.js 程序初始化時的高解析度毫秒時間戳。

performanceNodeTiming.v8Start#

V8 平台初始化時的高解析度毫秒時間戳。

類別:PerformanceResourceTiming#

提供有關應用程式資源載入的詳細網路計時資料。

此類別的建構函式不會直接公開給使用者。

performanceResourceTiming.workerStart#

在立即傳送 fetch 要求之前的高解析度毫秒時間戳。如果資源未被工作執行緒攔截,則此屬性永遠會傳回 0。

performanceResourceTiming.redirectStart#

代表啟動重新導向的擷取開始時間的高解析度毫秒時間戳。

performanceResourceTiming.redirectEnd#

在收到最後一次重新導向回應的最後一個位元組後,立即建立的高解析度毫秒時間戳。

performanceResourceTiming.fetchStart#

Node.js 開始擷取資源之前的高解析度毫秒時間戳。

performanceResourceTiming.domainLookupStart#

在 Node.js 開始為資源進行網域名稱查詢之前的高解析度毫秒時間戳記。

performanceResourceTiming.domainLookupEnd#

在 Node.js 完成資源的網域名稱查詢之後的高解析度毫秒時間戳記。

performanceResourceTiming.connectStart#

在 Node.js 開始建立與伺服器的連線以擷取資源之前的高解析度毫秒時間戳記。

performanceResourceTiming.connectEnd#

在 Node.js 完成建立與伺服器的連線以擷取資源之後的高解析度毫秒時間戳記。

performanceResourceTiming.secureConnectionStart#

在 Node.js 開始握手程序以確保目前連線之前的高解析度毫秒時間戳記。

performanceResourceTiming.requestStart#

在 Node.js 從伺服器收到回應的第一個位元組之前的高解析度毫秒時間戳記。

performanceResourceTiming.responseEnd#

高解析度毫秒時間戳,代表 Node.js 收到資源最後一個位元組或傳輸連線關閉(以先發生的為準)之後的時間。

performanceResourceTiming.transferSize#

一個數字,代表已擷取資源的大小(以位元組為單位)。大小包含回應標頭欄位加上回應有效負載主體。

performanceResourceTiming.encodedBodySize#

一個數字,代表從擷取(HTTP 或快取)收到的有效負載主體大小(以位元組為單位),在移除任何套用的內容編碼之前。

performanceResourceTiming.decodedBodySize#

一個數字,代表從擷取(HTTP 或快取)收到的訊息主體大小(以位元組為單位),在移除任何套用的內容編碼之後。

performanceResourceTiming.toJSON()#

傳回一個 object,為 PerformanceResourceTiming 物件的 JSON 表示。

類別:PerformanceObserver#

PerformanceObserver.supportedEntryTypes#

取得支援的類型。

new PerformanceObserver(callback)#

PerformanceObserver 物件會在新的 PerformanceEntry 執行個體新增到效能時間軸時提供通知。

const {
  performance,
  PerformanceObserver,
} = require('node:perf_hooks');

const obs = new PerformanceObserver((list, observer) => {
  console.log(list.getEntries());

  performance.clearMarks();
  performance.clearMeasures();
  observer.disconnect();
});
obs.observe({ entryTypes: ['mark'], buffered: true });

performance.mark('test'); 

由於 PerformanceObserver 執行個體會引入自己的額外效能負擔,因此不應讓執行個體無限期地訂閱通知。使用者應在不再需要時立即中斷觀察者。

PerformanceObserver 收到關於新的 PerformanceEntry 執行個體的通知時,會呼叫 callback。回呼函式會收到一個 PerformanceObserverEntryList 執行個體和一個 PerformanceObserver 的參考。

performanceObserver.disconnect()#

中斷 PerformanceObserver 執行個體與所有通知的關聯。

performanceObserver.observe(options)#

  • options <物件>
    • type <string> 單一 <PerformanceEntry> 類型。如果已指定 entryTypes,則不得提供。
    • entryTypes <string[]> 識別觀察者有興趣的 <PerformanceEntry> 執行個體類型的字串陣列。如果未提供,將擲回錯誤。
    • buffered <boolean> 如果為 true,觀察者回呼函式會使用全球 PerformanceEntry 快取條目清單呼叫。如果為 false,只有在時間點之後建立的 PerformanceEntry 會傳送給觀察者回呼函式。預設值:false

訂閱 <PerformanceObserver> 實例,以接收由 options.entryTypesoptions.type 識別的新 <PerformanceEntry> 實例的通知

const {
  performance,
  PerformanceObserver,
} = require('node:perf_hooks');

const obs = new PerformanceObserver((list, observer) => {
  // Called once asynchronously. `list` contains three items.
});
obs.observe({ type: 'mark' });

for (let n = 0; n < 3; n++)
  performance.mark(`test${n}`); 

類別:PerformanceObserverEntryList#

PerformanceObserverEntryList 類別用於提供對傳遞給 PerformanceObserverPerformanceEntry 實例的存取。此類別的建構函式不會公開給使用者。

performanceObserverEntryList.getEntries()#

傳回 PerformanceEntry 物件的清單,這些物件以 performanceEntry.startTime 為準,依時間順序排列。

const {
  performance,
  PerformanceObserver,
} = require('node:perf_hooks');

const obs = new PerformanceObserver((perfObserverList, observer) => {
  console.log(perfObserverList.getEntries());
  /**
   * [
   *   PerformanceEntry {
   *     name: 'test',
   *     entryType: 'mark',
   *     startTime: 81.465639,
   *     duration: 0,
   *     detail: null
   *   },
   *   PerformanceEntry {
   *     name: 'meow',
   *     entryType: 'mark',
   *     startTime: 81.860064,
   *     duration: 0,
   *     detail: null
   *   }
   * ]
   */

  performance.clearMarks();
  performance.clearMeasures();
  observer.disconnect();
});
obs.observe({ type: 'mark' });

performance.mark('test');
performance.mark('meow'); 

performanceObserverEntryList.getEntriesByName(name[, type])#

傳回一個 `PerformanceEntry` 物件清單,依據 `performanceEntry.startTime` 的時間順序排列,其 `performanceEntry.name` 等於 `name`,且(可選擇)其 `performanceEntry.entryType` 等於 `type`。

const {
  performance,
  PerformanceObserver,
} = require('node:perf_hooks');

const obs = new PerformanceObserver((perfObserverList, observer) => {
  console.log(perfObserverList.getEntriesByName('meow'));
  /**
   * [
   *   PerformanceEntry {
   *     name: 'meow',
   *     entryType: 'mark',
   *     startTime: 98.545991,
   *     duration: 0,
   *     detail: null
   *   }
   * ]
   */
  console.log(perfObserverList.getEntriesByName('nope')); // []

  console.log(perfObserverList.getEntriesByName('test', 'mark'));
  /**
   * [
   *   PerformanceEntry {
   *     name: 'test',
   *     entryType: 'mark',
   *     startTime: 63.518931,
   *     duration: 0,
   *     detail: null
   *   }
   * ]
   */
  console.log(perfObserverList.getEntriesByName('test', 'measure')); // []

  performance.clearMarks();
  performance.clearMeasures();
  observer.disconnect();
});
obs.observe({ entryTypes: ['mark', 'measure'] });

performance.mark('test');
performance.mark('meow'); 

performanceObserverEntryList.getEntriesByType(type)#

傳回一個 `PerformanceEntry` 物件清單,依據 `performanceEntry.startTime` 的時間順序排列,其 `performanceEntry.entryType` 等於 `type`。

const {
  performance,
  PerformanceObserver,
} = require('node:perf_hooks');

const obs = new PerformanceObserver((perfObserverList, observer) => {
  console.log(perfObserverList.getEntriesByType('mark'));
  /**
   * [
   *   PerformanceEntry {
   *     name: 'test',
   *     entryType: 'mark',
   *     startTime: 55.897834,
   *     duration: 0,
   *     detail: null
   *   },
   *   PerformanceEntry {
   *     name: 'meow',
   *     entryType: 'mark',
   *     startTime: 56.350146,
   *     duration: 0,
   *     detail: null
   *   }
   * ]
   */
  performance.clearMarks();
  performance.clearMeasures();
  observer.disconnect();
});
obs.observe({ type: 'mark' });

performance.mark('test');
performance.mark('meow'); 

perf_hooks.createHistogram([options])#

  • options <物件>
    • lowest <number> | <bigint> 最低可辨識值。必須為大於 0 的整數值。預設:1
    • highest <number> | <bigint> 可記錄的最高值。必須等於或大於 lowest 兩倍的整數值。預設值:Number.MAX_SAFE_INTEGER
    • figures <number> 精確位數。必須介於 15 之間的數字。預設值:3
  • 傳回:<RecordableHistogram>

傳回 <RecordableHistogram>

perf_hooks.monitorEventLoopDelay([options])#

此屬性是 Node.js 的擴充功能。在 Web 瀏覽器中無法使用。

建立 IntervalHistogram 物件,用於取樣並回報事件迴圈延遲。延遲將以奈秒為單位回報。

使用計時器偵測近似事件迴圈延遲的原因,在於計時器的執行特別與 libuv 事件迴圈的生命週期相關。換句話說,迴圈延遲會導致計時器執行延遲,而這正是此 API 旨在偵測的延遲。

const { monitorEventLoopDelay } = require('node:perf_hooks');
const h = monitorEventLoopDelay({ resolution: 20 });
h.enable();
// Do something.
h.disable();
console.log(h.min);
console.log(h.max);
console.log(h.mean);
console.log(h.stddev);
console.log(h.percentiles);
console.log(h.percentile(50));
console.log(h.percentile(99)); 

類別:Histogram#

histogram.count#

直方圖記錄的範例數量。

histogram.countBigInt#

直方圖記錄的範例數量。

histogram.exceeds#

事件循環延遲超過最大 1 小時事件循環延遲閾值的次數。

histogram.exceedsBigInt#

事件循環延遲超過最大 1 小時事件循環延遲閾值的次數。

histogram.max#

記錄到的最大事件循環延遲。

histogram.maxBigInt#

記錄到的最大事件循環延遲。

histogram.mean#

記錄到的事件循環延遲的平均值。

histogram.min#

記錄到的最小事件循環延遲。

histogram.minBigInt#

記錄到的最小事件循環延遲。

histogram.percentile(percentile)#

  • percentile <number> 介於 (0, 100] 範圍內的百分位數值。
  • 傳回:<數字>

傳回給定百分位數的值。

histogram.percentileBigInt(percentile)#

  • percentile <number> 介於 (0, 100] 範圍內的百分位數值。
  • 傳回:<bigint>

傳回給定百分位數的值。

histogram.percentiles#

傳回一個詳細說明累積百分比分佈的 Map 物件。

histogram.percentilesBigInt#

傳回一個詳細說明累積百分比分佈的 Map 物件。

histogram.reset()#

重設收集的直方圖資料。

histogram.stddev#

記錄的事件迴圈延遲的標準差。

類別:IntervalHistogram extends Histogram#

在給定間隔定期更新的 Histogram

histogram.disable()#

停用更新間隔計時器。如果計時器已停止,傳回 true;如果已停止,傳回 false

histogram.enable()#

啟用更新間隔計時器。如果計時器已啟動,傳回 true;如果已啟動,傳回 false

複製 IntervalHistogram#

<IntervalHistogram> 執行個體可透過 <MessagePort> 複製。在接收端,直方圖會複製為一個純粹的 <Histogram> 物件,不實作 enable()disable() 方法。

類別:RecordableHistogram 繼承 Histogram#

histogram.add(other)#

other 的值新增到這個直方圖。

histogram.record(val)#

histogram.recordDelta()#

計算自上次呼叫 recordDelta() 以來經過的時間量(以奈秒為單位),並將該時間量記錄在直方圖中。

範例#

測量非同步操作的持續時間#

以下範例使用 非同步掛鉤 和效能 API 來測量 Timeout 操作的實際持續時間(包括執行回呼所花費的時間)。

'use strict';
const async_hooks = require('node:async_hooks');
const {
  performance,
  PerformanceObserver,
} = require('node:perf_hooks');

const set = new Set();
const hook = async_hooks.createHook({
  init(id, type) {
    if (type === 'Timeout') {
      performance.mark(`Timeout-${id}-Init`);
      set.add(id);
    }
  },
  destroy(id) {
    if (set.has(id)) {
      set.delete(id);
      performance.mark(`Timeout-${id}-Destroy`);
      performance.measure(`Timeout-${id}`,
                          `Timeout-${id}-Init`,
                          `Timeout-${id}-Destroy`);
    }
  },
});
hook.enable();

const obs = new PerformanceObserver((list, observer) => {
  console.log(list.getEntries()[0]);
  performance.clearMarks();
  performance.clearMeasures();
  observer.disconnect();
});
obs.observe({ entryTypes: ['measure'], buffered: true });

setTimeout(() => {}, 1000); 

測量載入依賴項所需的時間#

以下範例測量載入依賴項的 require() 操作的持續時間

'use strict';
const {
  performance,
  PerformanceObserver,
} = require('node:perf_hooks');
const mod = require('node:module');

// Monkey patch the require function
mod.Module.prototype.require =
  performance.timerify(mod.Module.prototype.require);
require = performance.timerify(require);

// Activate the observer
const obs = new PerformanceObserver((list) => {
  const entries = list.getEntries();
  entries.forEach((entry) => {
    console.log(`require('${entry[0]}')`, entry.duration);
  });
  performance.clearMarks();
  performance.clearMeasures();
  obs.disconnect();
});
obs.observe({ entryTypes: ['function'], buffered: true });

require('some-module'); 

測量一次 HTTP 回應行程所需的時間#

以下範例用於追蹤 HTTP 伺服器 (OutgoingMessage) 和 HTTP 要求 (IncomingMessage) 所花費的時間。對於 HTTP 伺服器來說,表示從開始要求到收到回應之間的時間區間,而對於 HTTP 要求來說,表示從收到要求到傳送回應之間的時間區間

'use strict';
const { PerformanceObserver } = require('node:perf_hooks');
const http = require('node:http');

const obs = new PerformanceObserver((items) => {
  items.getEntries().forEach((item) => {
    console.log(item);
  });
});

obs.observe({ entryTypes: ['http'] });

const PORT = 8080;

http.createServer((req, res) => {
  res.end('ok');
}).listen(PORT, () => {
  http.get(`http://127.0.0.1:${PORT}`);
}); 

測量連線成功時 net.connect (僅適用於 TCP) 所花費的時間#

'use strict';
const { PerformanceObserver } = require('node:perf_hooks');
const net = require('node:net');
const obs = new PerformanceObserver((items) => {
  items.getEntries().forEach((item) => {
    console.log(item);
  });
});
obs.observe({ entryTypes: ['net'] });
const PORT = 8080;
net.createServer((socket) => {
  socket.destroy();
}).listen(PORT, () => {
  net.connect(PORT);
}); 

測量要求成功時 DNS 所花費的時間#

'use strict';
const { PerformanceObserver } = require('node:perf_hooks');
const dns = require('node:dns');
const obs = new PerformanceObserver((items) => {
  items.getEntries().forEach((item) => {
    console.log(item);
  });
});
obs.observe({ entryTypes: ['dns'] });
dns.lookup('localhost', () => {});
dns.promises.resolve('localhost');