Node.js v18.18.2 文档


目录

性能测量 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.startTime按时间顺序排列的PerformanceEntry 对象的列表。如果您只对某些类型或具有某些名称的性能条目感兴趣,请参阅 performance.getEntriesByType()performance.getEntriesByName()

performance.getEntriesByName(name[, type])#

按时间顺序返回关于performanceEntry.startTimePerformanceEntry对象列表,其performanceEntry.name等于name,并且可选地,其performanceEntry.entryType等于 type

performance.getEntriesByType(type)#

返回关于performanceEntry.startTime的按时间顺序排列的PerformanceEntry对象列表,其中performanceEntry.entryType 等于type

performance.mark([name[, options]])#

  • name <字符串>
  • options <对象>
    • detail <any>标记中包含的其他可选详细信息。
    • startTime <number>用作标记时间的可选时间戳。 默认值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 <any>要包含在措施中的其他可选详细信息。
    • duration <number>开始时间和结束时间之间的持续时间。
    • end <数字> | <string>用作结束时间的时间戳,或标识先前记录标记的字符串。
    • start <数字> | <string>用作开始时间的时间戳,或标识先前记录标记的字符串。
  • endMark <string>可选。如果startMarkOrOptions<Object> ,则必须省略。

在性能时间轴中创建一个新的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 浏览器中不可用。

将函数包装在新函数中,该函数测量包装函数的运行时间。PerformanceObserver必须订阅'function' 事件类型才能访问计时详细信息。

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(); 

如果包装的函数返回一个 Promise ,则最终处理程序将附加到该 Promise ,并且一旦调用最终处理程序,就会报告持续时间。

performance.toJSON()#

一个对象,它是performance对象的 JSON 表示形式。它类似于浏览器中的window.performance.toJSON

事件:'resourcetimingbufferfull'#

当全局性能资源计时缓冲区已满时,会触发'resourcetimingbufferfull'事件。在事件侦听器中使用performance.setResourceTimingBufferSize()调整资源计时缓冲区大小 或使用performance.clearResourceTimings()清除缓冲区 ,以允许将更多条目添加到性能时间线缓冲区。

类:PerformanceEntry#

performanceEntry.detail#

特定于entryType的其他详细信息。

performanceEntry.duration#

此条目所经过的总毫秒数。该值对于所有性能条目类型都没有意义。

performanceEntry.entryType#

性能条目的类型。它可能是以下之一:

  • 'node'(仅限 Node.js)
  • 'mark'(可在网络上获取)
  • 'measure'(可在网络上获取)
  • 'gc'(仅限 Node.js)
  • 'function'(仅限 Node.js)
  • 'http2'(仅限 Node.js)
  • 'http'(仅限 Node.js)

performanceEntry.flags#

该属性是 Node.js 的扩展。它在 Web 浏览器中不可用。

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

performanceEntry.name#

表演条目的名称。

performanceEntry.kind#

该属性是 Node.js 的扩展。它在 Web 浏览器中不可用。

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

performanceEntry.startTime#

高分辨率毫秒时间戳,标记性能条目的开始时间。

垃圾收集('gc')详细信息#

performanceEntry.type等于'gc'时,performanceEntry.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'时,performanceEntry.detail 属性将是包含附加信息的<Object>

如果performanceEntry.name等于HttpClient,则detail 将包含以下属性:reqresreq属性将是一个<Object>,其中包含methodurlheadersres属性将是一个包含statusCodestatusMessageheaders<Object>

如果performanceEntry.name等于HttpRequest,则detail 将包含以下属性:reqresreq属性将是一个<Object>,其中包含methodurlheadersres属性将是一个包含statusCodestatusMessageheaders<Object>

这可能会增加额外的内存开销,并且只能用于诊断目的,而不是默认在生产中打开。

HTTP/2('http2')详细信息#

performanceEntry.type等于'http2'时, performanceEntry.detail属性将是包含附加性能信息的<Object> 。

如果performanceEntry.name等于Http2Stream,则detail 将包含以下属性:

  • bytesRead <number>为此 Http2Stream接收的DATA 帧字节数。
  • bytesWritten <number>为此 Http2Stream发送的DATA 帧字节数。
  • id <number>关联的Http2Stream的标识符
  • timeToFirstByte <number>从PerformanceEntry startTime到接收第一个DATA帧之间经过的毫秒数 。
  • timeToFirstByteSent <number>从PerformanceEntry startTime到发送第一个DATA帧之间经过的毫秒数。
  • timeToFirstHeader <number> PerformanceEntry startTime和接收第一个标头之间经过的毫秒数 。

如果performanceEntry.name等于Http2Session,则detail将包含以下属性:

  • bytesRead <number>此Http2Session收到的字节数。
  • bytesWritten <number>为此Http2Session发送的字节数。
  • framesReceived <number> Http2Session接收到的 HTTP/2 帧数 。
  • framesSent <number>由Http2Session发送的 HTTP/2 帧数。
  • maxConcurrentStreams <number>在Http2Session的生命周期内同时打开的最大流数。
  • pingRTT <number>自传输PING帧和接收其确认以来经过的毫秒数。仅当在Http2Session上发送了PING帧时才出现。
  • streamAverageDuration <number>所有Http2Stream实例的平均持续时间(以毫秒为单位)。
  • streamCount<number> Http2Session 处理的 Http2Stream实例的数量。
  • type <string> 'server''client'来标识Http2Session的类型 。

Timerify('函数')详细信息#

performanceEntry.type等于'function'时, performanceEntry.detail属性将是一个<Array>,列出定时函数的输入参数。

net(“net”)详细信息#

performanceEntry.type等于'net'时, performanceEntry.detail属性将是包含附加信息的<Object>

如果performanceEntry.name等于connect,则detail 将包含以下属性:hostport

DNS ('dns') 详细信息#

performanceEntry.type等于'dns'时, performanceEntry.detail属性将是包含附加信息的<Object>

如果performanceEntry.name等于lookup,则detail 将包含以下属性:hostnamefamilyhintsverbatimaddresses

如果performanceEntry.name等于lookupService,则detail将包含以下属性:hostporthostname , service

如果performanceEntry.name等于queryxxxgetHostByAddr,则detail将包含以下属性:hostttlresultresult的值与queryxxxgetHostByAddr的结果相同。

类:PerformanceNodeTiming#

该属性是 Node.js 的扩展。它在 Web 浏览器中不可用。

提供 Node.js 本身的计时详细信息。该类的构造函数不向用户公开。

performanceNodeTiming.bootstrapComplete#

Node.js 进程完成引导的高分辨率毫秒时间戳。如果引导尚未完成,则该属性的值为 -1。

performanceNodeTiming.environment#

Node.js 环境初始化时的高分辨率毫秒时间戳。

performanceNodeTiming.idleTime#

事件循环在事件提供程序中空闲的时间量的高分辨率毫秒时间戳(例如epoll_wait)。这没有考虑 CPU 使用率。如果事件循环尚未启动(例如,在主脚本的第一个tick中),则该属性的值为0。

performanceNodeTiming.loopExit#

Node.js 事件循环退出时的高分辨率毫秒时间戳。如果事件循环尚未退出,则该属性的值为 -1。'exit'事件的处理程序中,它的值只能为非 -1 。

performanceNodeTiming.loopStart#

Node.js 事件循环开始的高分辨率毫秒时间戳。如果事件循环尚未启动(例如,在主脚本的第一个tick中),则该属性的值为-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 表示形式

类:perf_hooks.PerformanceObserver#

PerformanceObserver.supportedEntryTypes#

获取支持的类型。

new PerformanceObserver(callback)#

当新的PerformanceEntry实例添加到性能时间轴时,PerformanceObserver对象会提供通知 。

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.startTime按时间顺序排列的PerformanceEntry对象的列表。

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
   *   },
   *   PerformanceEntry {
   *     name: 'meow',
   *     entryType: 'mark',
   *     startTime: 81.860064,
   *     duration: 0
   *   }
   * ]
   */

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

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

performanceObserverEntryList.getEntriesByName(name[, type])#

按时间顺序返回相对于performanceEntry.startTimePerformanceEntry对象列表,其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
   *   }
   * ]
   */
  console.log(perfObserverList.getEntriesByName('nope')); // []

  console.log(perfObserverList.getEntriesByName('test', 'mark'));
  /**
   * [
   *   PerformanceEntry {
   *     name: 'test',
   *     entryType: 'mark',
   *     startTime: 63.518931,
   *     duration: 0
   *   }
   * ]
   */
  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.startTime 的按时间顺序排列的PerformanceEntry对象列表,其中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
   *   },
   *   PerformanceEntry {
   *     name: 'meow',
   *     entryType: 'mark',
   *     startTime: 56.350146,
   *     duration: 0
   *   }
   * ]
   */
  performance.clearMarks();
  performance.clearMeasures();
  observer.disconnect();
});
obs.observe({ type: 'mark' });

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

perf_hooks.createHistogram([options])#

  • options <对象>
    • lowest <数字> | <bigint>最低可辨别值。必须是大于 0 的整数值。默认值: 1
    • highest <数字> | <bigint>最高可记录值。必须是等于或大于两倍lowest的整数值。 默认值: Number.MAX_SAFE_INTEGER
    • figures <number>准确度位数。必须是15之间的数字 。默认值: 3
  • 返回<可记录直方图>

返回一个<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)#

返回给定百分位数的值。

histogram.percentileBigInt(percentile)#

返回给定百分位数的值。

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 extends Histogram#

histogram.add(other)#

other中的值添加到此直方图中。

histogram.record(val)#

histogram.recordDelta()#

计算自上次调用recordDelta()以来经过的时间量(以纳秒为单位)并将该时间量记录在直方图中。

例子#

测量异步操作的持续时间#

以下示例使用Async Hooks和 Performance 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'); 

NodeJS中文文档为Read dev Docs平台提供托管,中文NodeJS文档均由英文版NodeJS文档翻译,版权属于nodejs.org