性能测量 API
源代码: lib/perf_hooks.js
此模块提供 W3C Web 性能 API 的子集实现,以及 Node.js 特定性能测量的附加 API。
Node.js 支持以下 Web 性能 API:
import { performance, PerformanceObserver } from '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')
})
const { PerformanceObserver, performance } = require('node:perf_hooks')
const obs = new PerformanceObserver(items => {
console.log(items.getEntries()[0].duration)
})
obs.observe({ type: 'measure' })
performance.measure('Start to Now')
performance.mark('A')
;(async function doSomeLongRunningProcess() {
await new Promise(r => setTimeout(r, 5000))
performance.measure('A to Now', 'A')
performance.mark('B')
performance.measure('A to B', 'A', 'B')
})()
perf_hooks.performance
新增于: v8.5.0
一个可用于收集当前 Node.js 实例性能指标的对象。它类似于浏览器中的 window.performance
。
performance.clearMarks([name])
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此方法必须使用 performance 对象作为接收者调用。 |
v8.5.0 | 新增于: v8.5.0 |
name
<string>
如果未提供 name
,则会从性能时间线中移除所有 PerformanceMark
对象。如果提供了 name
,则只移除指定的标记。
performance.clearMeasures([name])
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此方法必须使用 performance 对象作为接收者调用。 |
v16.7.0 | 新增于: v16.7.0 |
name
<string>
如果未提供 name
,则会从性能时间线中移除所有 PerformanceMeasure
对象。如果提供了 name
,则只移除指定的度量。
performance.clearResourceTimings([name])
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此方法必须使用 performance 对象作为接收者调用。 |
v18.2.0, v16.17.0 | 新增于:v18.2.0, v16.17.0 |
name
<字符串>
如果未提供 name
,则会从资源时间线中移除所有 PerformanceResourceTiming
对象。如果提供了 name
,则仅移除指定名称的资源。
performance.eventLoopUtilization([utilization1[, utilization2]])
新增于:v14.10.0, v12.19.0
utilization1
<对象> 之前调用eventLoopUtilization()
的结果。utilization2
<对象> 在utilization1
之前调用eventLoopUtilization()
的结果。- 返回值:<对象>
eventLoopUtilization()
方法返回一个对象,该对象包含事件循环处于空闲和活动状态的累积持续时间,以高精度毫秒计时器表示。utilization
值是计算出的事件循环利用率 (ELU)。
如果主线程上的引导程序尚未完成,则属性值为 0
。由于引导程序发生在事件循环内,因此 ELU 在 工作线程 上可以立即使用。
utilization1
和 utilization2
都是可选参数。
如果传递了 utilization1
,则计算并返回当前调用的 active
和 idle
时间之间的差值,以及相应的 utilization
值(类似于 process.hrtime()
)。
如果同时传递了 utilization1
和 utilization2
,则计算这两个参数之间的差值。这是一个方便的选项,因为与 process.hrtime()
不同,计算 ELU 比简单的减法更复杂。
ELU 类似于 CPU 利用率,但它只测量事件循环统计信息,而不是 CPU 使用率。它表示事件循环在事件循环的事件提供程序(例如 epoll_wait
)之外花费的时间百分比。不会考虑其他 CPU 空闲时间。以下是如何使大部分空闲进程具有高 ELU 的示例。
import { eventLoopUtilization } from 'node:perf_hooks'
import { spawnSync } from 'node:child_process'
setImmediate(() => {
const elu = eventLoopUtilization()
spawnSync('sleep', ['5'])
console.log(eventLoopUtilization(elu).utilization)
})
'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()
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此方法必须使用 performance 对象作为接收者调用。 |
v16.7.0 | 新增于:v16.7.0 |
按 performanceEntry.startTime
的时间顺序返回 PerformanceEntry
对象列表。如果您只对特定类型或具有特定名称的性能条目感兴趣,请参阅 performance.getEntriesByType()
和 performance.getEntriesByName()
。
performance.getEntriesByName(name[, type])
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此方法必须使用 performance 对象作为接收者调用。 |
v16.7.0 | 新增于:v16.7.0 |
name
<string>type
<string>- 返回值:<PerformanceEntry[]>
按 performanceEntry.startTime
的时间顺序返回 PerformanceEntry
对象列表,这些对象的 performanceEntry.name
等于 name
,并且可选地,其 performanceEntry.entryType
等于 type
。
performance.getEntriesByType(type)
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此方法必须使用 performance 对象作为接收者调用。 |
v16.7.0 | 新增于:v16.7.0 |
type
<字符串>- 返回值: <PerformanceEntry[]>
返回一个 PerformanceEntry
对象列表,这些对象按 performanceEntry.startTime
的时间顺序排列,其 performanceEntry.entryType
等于 type
。
performance.mark(name[, options])
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此方法必须使用 performance 对象作为接收者调用。name 参数不再是可选的。 |
v16.0.0 | 更新为符合用户计时级别 3 规范。 |
v8.5.0 | 新增于:v8.5.0 |
在性能时间线中创建一个新的 PerformanceMark
条目。PerformanceMark
是 PerformanceEntry
的一个子类,其 performanceEntry.entryType
始终为 'mark'
,其 performanceEntry.duration
始终为 0
。性能标记用于标记性能时间线中特定重要的时刻。
创建的 PerformanceMark
条目被放入全局性能时间线中,并且可以使用 performance.getEntries
、performance.getEntriesByName
和 performance.getEntriesByType
查询。当执行观察时,应使用 performance.clearMarks
手动清除全局性能时间线中的条目。
performance.markResourceTiming(timingInfo, requestedUrl, initiatorType, global, cacheMode, bodyInfo, responseStatus[, deliveryType])
[历史]
版本 | 变更 |
---|---|
v22.2.0 | 添加了 bodyInfo 、responseStatus 和 deliveryType 参数。 |
v18.2.0, v16.17.0 | 在 v18.2.0, v16.17.0 版本中添加 |
timingInfo
<对象> 获取计时信息requestedUrl
<字符串> 资源 URLinitiatorType
<字符串> 发起者名称,例如:'fetch'global
<对象>cacheMode
<字符串> 缓存模式必须为空字符串 ('') 或 'local'bodyInfo
<对象> 获取响应体信息responseStatus
<数字> 响应的状态码deliveryType
<字符串> 传输类型。默认值:''
。
此属性是 Node.js 的扩展,在 Web 浏览器中不可用。
在资源时间线中创建一个新的 PerformanceResourceTiming
条目。PerformanceResourceTiming
是 PerformanceEntry
的子类,其 performanceEntry.entryType
始终为 'resource'
。性能资源用于标记资源时间线中的时刻。
创建的 PerformanceMark
条目将放入全局资源时间线中,并且可以使用 performance.getEntries
、performance.getEntriesByName
和 performance.getEntriesByType
进行查询。执行观察后,应使用 performance.clearResourceTimings
手动清除全局性能时间线中的条目。
performance.measure(name[, startMarkOrOptions[, endMark]])
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此方法必须使用 performance 对象作为接收者调用。 |
v16.0.0 | 更新为符合用户计时级别 3 规范。 |
v13.13.0, v12.16.3 | 使 startMark 和 endMark 参数可选。 |
v8.5.0 | 在 v8.5.0 中添加 |
name
<字符串>
在性能时间线中创建一个新的 PerformanceMeasure
条目。PerformanceMeasure
是 PerformanceEntry
的子类,其 performanceEntry.entryType
始终为 'measure'
,其 performanceEntry.duration
测量自 startMark
和 endMark
以来经过的毫秒数。
startMark
参数可以标识性能时间线中任何 现有 的 PerformanceMark
,或者可以标识 PerformanceNodeTiming
类提供的任何时间戳属性。如果指定的 startMark
不存在,则会抛出错误。
可选的 endMark
参数必须标识性能时间线中任何 现有 的 PerformanceMark
或 PerformanceNodeTiming
类提供的任何时间戳属性。如果没有传递参数,则 endMark
将为 performance.now()
,否则,如果指定的 endMark
不存在,则会抛出错误。
创建的 PerformanceMeasure
条目将放入全局性能时间线中,并可以使用 performance.getEntries
、performance.getEntriesByName
和 performance.getEntriesByType
查询。执行观察后,应使用 performance.clearMeasures
手动清除全局性能时间线中的条目。
performance.nodeTiming
新增于:v8.5.0
此属性为 Node.js 的扩展。在 Web 浏览器中不可用。
PerformanceNodeTiming
类的一个实例,提供 Node.js 特定操作里程碑的性能指标。
performance.now()
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此方法必须使用 performance 对象作为接收者来调用。 |
v8.5.0 | 新增于:v8.5.0 |
- 返回值:<number>
返回当前高分辨率毫秒时间戳,其中 0 代表当前 node
进程的开始。
performance.setResourceTimingBufferSize(maxSize)
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此方法必须使用 performance 对象作为接收者来调用。 |
v18.8.0 | 新增于:v18.8.0 |
将全局性能资源计时缓冲区大小设置为指定数量的“资源”类型性能条目对象。
默认情况下,最大缓冲区大小设置为 250。
performance.timeOrigin
新增于:v8.5.0
timeOrigin
指定当前 node
进程开始时的高精度毫秒时间戳,以 Unix 时间计量。
performance.timerify(fn[, options])
[历史]
版本 | 变更 |
---|---|
v16.0.0 | 添加了直方图选项。 |
v16.0.0 | 重新实现为使用纯 JavaScript 并能够计时异步函数。 |
v8.5.0 | 新增于:v8.5.0 |
fn
<函数>options
<对象>histogram
<RecordableHistogram> 使用perf_hooks.createHistogram()
创建的直方图对象,用于记录以纳秒为单位的运行时间。
此属性是 Node.js 的扩展。它在 Web 浏览器中不可用。
将函数包装在一个新函数中,该新函数测量包装函数的运行时间。必须将 PerformanceObserver
订阅到 'function'
事件类型,才能访问计时详细信息。
import { performance, PerformanceObserver } from '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'] })
// 将创建一个性能时间线条目
wrapped()
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'] })
// 将创建一个性能时间线条目
wrapped()
如果包装的函数返回一个 Promise,则会将 finally 处理程序附加到 Promise,并且一旦调用 finally 处理程序,就会报告持续时间。
performance.toJSON()
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此方法必须使用 performance 对象作为接收者来调用。 |
v16.1.0 | 新增于:v16.1.0 |
一个表示 performance
对象的 JSON 对象。它类似于浏览器中的 window.performance.toJSON
。
事件:'resourcetimingbufferfull'
新增于:v18.8.0
当全局性能资源计时缓冲区已满时,将触发 'resourcetimingbufferfull'
事件。使用 performance.setResourceTimingBufferSize()
调整资源计时缓冲区大小,或在事件监听器中使用 performance.clearResourceTimings()
清除缓冲区,以允许将更多条目添加到性能时间线缓冲区。
类:PerformanceEntry
新增于:v8.5.0
此类的构造函数不会直接公开给用户。
performanceEntry.duration
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此属性 getter 必须使用 PerformanceEntry 对象作为接收者来调用。 |
v8.5.0 | 新增于:v8.5.0 |
此条目的总毫秒数。此值并非对所有性能条目类型都有意义。
performanceEntry.entryType
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此属性 getter 必须使用 PerformanceEntry 对象作为接收者来调用。 |
v8.5.0 | 在 v8.5.0 中添加 |
性能条目的类型。它可能是以下之一:
'dns'
(仅限 Node.js)'function'
(仅限 Node.js)'gc'
(仅限 Node.js)'http2'
(仅限 Node.js)'http'
(仅限 Node.js)'mark'
(可在 Web 上使用)'measure'
(可在 Web 上使用)'net'
(仅限 Node.js)'node'
(仅限 Node.js)'resource'
(可在 Web 上使用)
performanceEntry.name
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此属性 getter 必须使用 PerformanceEntry 对象作为接收者来调用。 |
v8.5.0 | 在 v8.5.0 中添加 |
性能条目的名称。
performanceEntry.startTime
[历史记录]
版本 | 变更 |
---|---|
v19.0.0 | 此属性 getter 必须使用 PerformanceEntry 对象作为接收者来调用。 |
v8.5.0 | 在 v8.5.0 中添加 |
表示性能记录起始时间的高精度毫秒时间戳。
类: PerformanceMark
在以下版本中添加: v18.2.0, v16.17.0
公开通过 Performance.mark()
方法创建的标记。
performanceMark.detail
[历史记录]
版本 | 变更 |
---|---|
v19.0.0 | 此属性 getter 必须使用 PerformanceMark 对象作为接收者来调用。 |
v16.0.0 | 在 v16.0.0 中添加 |
使用 Performance.mark()
方法创建时指定的附加细节。
类: PerformanceMeasure
新增于: v18.2.0, v16.17.0
- 继承自: <PerformanceEntry>
公开通过 Performance.measure()
方法创建的度量。
此类的构造函数不会直接向用户公开。
performanceMeasure.detail
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此属性 getter 必须使用 PerformanceMeasure 对象作为接收者来调用。 |
v16.0.0 | 新增于: v16.0.0 |
使用 Performance.measure()
方法创建时指定的附加细节。
类: PerformanceNodeEntry
新增于: v19.0.0
- 继承自: <PerformanceEntry>
此类是 Node.js 的扩展。它在 Web 浏览器中不可用。
提供详细的 Node.js 时序数据。
此类的构造函数不会直接向用户公开。
performanceNodeEntry.detail
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此属性 getter 必须使用 PerformanceNodeEntry 对象作为接收者来调用。 |
v16.0.0 | 新增于: v16.0.0 |
特定于 entryType
的附加细节。
performanceNodeEntry.flags
[历史]
版本 | 变更 |
---|---|
v16.0.0 | 运行时已弃用。现在已移动到 entryType 为 'gc' 时的 detail 属性中。 |
v13.9.0, v12.17.0 | 添加于:v13.9.0, v12.17.0 |
当 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
[历史]
版本 | 变更 |
---|---|
v16.0.0 | 运行时已弃用。现在已移动到 entryType 为 'gc' 时的 detail 属性。 |
v8.5.0 | 新增于:v8.5.0 |
当 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
属性将是一个 <对象>,包含两个属性:
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
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
HTTP ('http') 详情
当 performanceEntry.type
等于 'http'
时,performanceNodeEntry.detail
属性将是一个包含附加信息的 <对象>。
如果 performanceEntry.name
等于 HttpClient
,则 detail
将包含以下属性:req
,res
。req
属性将是一个包含 method
,url
,headers
的 <对象>,res
属性将是一个包含 statusCode
,statusMessage
,headers
的 <对象>。
如果 performanceEntry.name
等于 HttpRequest
,则 detail
将包含以下属性:req
,res
。req
属性将是一个包含 method
,url
,headers
的 <对象>,res
属性将是一个包含 statusCode
,statusMessage
,headers
的 <对象>。
这可能会增加额外的内存开销,因此应仅用于诊断目的,不应默认情况下在生产环境中启用。
HTTP/2 ('http2') 详情
当 performanceEntry.type
等于 'http2'
时,performanceNodeEntry.detail
属性将是一个包含额外性能信息的 <对象>。
如果 performanceEntry.name
等于 Http2Stream
,则 detail
将包含以下属性:
bytesRead
<数字> 此Http2Stream
收到的DATA
帧字节数。bytesWritten
<数字> 此Http2Stream
发送的DATA
帧字节数。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
<数字>Http2Session
处理的Http2Stream
实例数。type
<字符串>'server'
或'client'
,用于标识Http2Session
的类型。
Timerify ('function') 详情
当 performanceEntry.type
等于 'function'
时,performanceNodeEntry.detail
属性将是一个 <数组>,列出计时函数的输入参数。
Net ('net') 详情
当 performanceEntry.type
等于 'net'
时,performanceNodeEntry.detail
属性将是一个 <对象>,包含附加信息。
如果 performanceEntry.name
等于 connect
,则 detail
将包含以下属性:host
,port
。
DNS ('dns') 详情
当 performanceEntry.type
等于 'dns'
时,performanceNodeEntry.detail
属性将是一个 <对象>,包含附加信息。
如果 performanceEntry.name
等于 lookup
,则 detail
将包含以下属性:hostname
,family
,hints
,verbatim
,addresses
。
如果 performanceEntry.name
等于 lookupService
,则 detail
将包含以下属性:host
,port
,hostname
,service
。
如果 performanceEntry.name
等于 queryxxx
或 getHostByAddr
,则 detail
将包含以下属性:host
,ttl
,result
。result
的值与 queryxxx
或 getHostByAddr
的结果相同。
类: PerformanceNodeTiming
新增于: v8.5.0
- 继承自: <PerformanceEntry>
此属性是 Node.js 的扩展。它在 Web 浏览器中不可用。
提供 Node.js 本身的时间细节。此类的构造函数对用户不可见。
performanceNodeTiming.bootstrapComplete
新增于: v8.5.0
Node.js 进程完成引导的高精度毫秒时间戳。如果引导尚未完成,则该属性的值为 -1。
performanceNodeTiming.environment
新增于: v8.5.0
Node.js 环境初始化的高精度毫秒时间戳。
performanceNodeTiming.idleTime
新增于: v14.10.0, v12.19.0
事件循环在事件循环的事件提供程序(例如 epoll_wait
)中空闲的时间的高精度毫秒时间戳。这不会考虑 CPU 使用率。如果事件循环尚未启动(例如,在主脚本的第一个 tick 中),则该属性的值为 0。
performanceNodeTiming.loopExit
新增于: v8.5.0
Node.js 事件循环退出的高精度毫秒时间戳。如果事件循环尚未退出,则该属性的值为 -1。只有在 'exit'
事件的处理程序中,它才能具有非 -1 的值。
performanceNodeTiming.loopStart
新增于: v8.5.0
Node.js 事件循环开始的高精度毫秒时间戳。如果事件循环尚未启动(例如,在主脚本的第一个 tick 中),则该属性的值为 -1。
performanceNodeTiming.nodeStart
新增于: v8.5.0
Node.js 进程初始化的高精度毫秒时间戳。
performanceNodeTiming.uvMetricsInfo
新增于: v22.8.0, v20.18.0
- 返回值: <Object>
这是 uv_metrics_info
函数的包装器。它返回当前的事件循环指标集。
建议在使用 setImmediate
调度的函数内部使用此属性,以避免在完成当前循环迭代期间安排的所有操作之前收集指标。
const { performance } = require('node:perf_hooks')
setImmediate(() => {
console.log(performance.nodeTiming.uvMetricsInfo)
})
import { performance } from 'node:perf_hooks'
setImmediate(() => {
console.log(performance.nodeTiming.uvMetricsInfo)
})
performanceNodeTiming.v8Start
新增于: v8.5.0
V8 平台初始化时的高精度毫秒时间戳。
类: PerformanceResourceTiming
新增于: v18.2.0, v16.17.0
- 继承自: <PerformanceEntry>
提供有关应用程序资源加载的详细网络计时数据。
此类的构造函数不会直接暴露给用户。
performanceResourceTiming.workerStart
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此属性 getter 必须使用 PerformanceResourceTiming 对象作为接收者来调用。 |
v18.2.0, v16.17.0 | 新增于: v18.2.0, v16.17.0 |
在分派 fetch
请求之前的立即高精度毫秒时间戳。如果资源没有被 worker 拦截,则此属性将始终返回 0。
performanceResourceTiming.redirectStart
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此属性 getter 必须以 PerformanceResourceTiming 对象作为接收者来调用。 |
v18.2.0, v16.17.0 | 添加于:v18.2.0, v16.17.0 |
表示启动重定向的提取开始时间的高精度毫秒时间戳。
performanceResourceTiming.redirectEnd
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此属性 getter 必须以 PerformanceResourceTiming 对象作为接收者来调用。 |
v18.2.0, v16.17.0 | 添加于:v18.2.0, v16.17.0 |
将在接收到最后一次重定向响应的最后一个字节后立即创建的高精度毫秒时间戳。
performanceResourceTiming.fetchStart
[历史记录]
版本 | 变更 |
---|---|
v19.0.0 | 此属性 getter 必须使用 PerformanceResourceTiming 对象作为接收者调用。 |
v18.2.0, v16.17.0 | 新增于:v18.2.0, v16.17.0 |
Node.js 开始获取资源之前的毫秒级高精度时间戳。
performanceResourceTiming.domainLookupStart
[历史记录]
版本 | 变更 |
---|---|
v19.0.0 | 此属性 getter 必须使用 PerformanceResourceTiming 对象作为接收者调用。 |
v18.2.0, v16.17.0 | 新增于:v18.2.0, v16.17.0 |
Node.js 开始为资源进行域名查找之前的毫秒级高精度时间戳。
performanceResourceTiming.domainLookupEnd
[历史记录]
版本 | 变更 |
---|---|
v19.0.0 | 此属性 getter 必须使用 PerformanceResourceTiming 对象作为接收者调用。 |
v18.2.0, v16.17.0 | 新增于:v18.2.0, v16.17.0 |
表示 Node.js 完成资源域名查找后的毫秒级高精度时间戳。
performanceResourceTiming.connectStart
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此属性 getter 必须以 PerformanceResourceTiming 对象作为接收者来调用。 |
v18.2.0, v16.17.0 | 新增于:v18.2.0, v16.17.0 |
表示 Node.js 开始建立与服务器连接以检索资源之前的瞬间的高精度毫秒时间戳。
performanceResourceTiming.connectEnd
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此属性 getter 必须以 PerformanceResourceTiming 对象作为接收者来调用。 |
v18.2.0, v16.17.0 | 新增于:v18.2.0, v16.17.0 |
表示 Node.js 完成建立与服务器连接以检索资源后的瞬间的高精度毫秒时间戳。
performanceResourceTiming.secureConnectionStart
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此属性 getter 必须使用 PerformanceResourceTiming 对象作为接收者来调用。 |
v18.2.0, v16.17.0 | 新增于:v18.2.0, v16.17.0 |
表示 Node.js 开始安全连接握手过程之前的毫秒级高精度时间戳。
performanceResourceTiming.requestStart
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此属性 getter 必须使用 PerformanceResourceTiming 对象作为接收者来调用。 |
v18.2.0, v16.17.0 | 新增于:v18.2.0, v16.17.0 |
表示 Node.js 从服务器接收响应的第一个字节之前的毫秒级高精度时间戳。
performanceResourceTiming.responseEnd
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此属性 getter 必须使用 PerformanceResourceTiming 对象作为接收者调用。 |
v18.2.0, v16.17.0 | 新增于:v18.2.0, v16.17.0 |
表示 Node.js 接收资源的最后一个字节之后的时间戳(毫秒级高精度),或传输连接关闭之前的时间戳(以先发生者为准)。
performanceResourceTiming.transferSize
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此属性 getter 必须使用 PerformanceResourceTiming 对象作为接收者调用。 |
v18.2.0, v16.17.0 | 新增于:v18.2.0, v16.17.0 |
表示已获取资源大小(以八位字节为单位)的数字。此大小包括响应报头字段和响应有效负载正文。
performanceResourceTiming.encodedBodySize
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此属性 getter 必须使用 PerformanceResourceTiming 对象作为接收者来调用。 |
v18.2.0, v16.17.0 | 新增于:v18.2.0, v16.17.0 |
表示从获取(HTTP 或缓存)接收到的有效负载正文大小(以八位字节为单位),在移除任何应用的内容编码之前。
performanceResourceTiming.decodedBodySize
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此属性 getter 必须使用 PerformanceResourceTiming 对象作为接收者来调用。 |
v18.2.0, v16.17.0 | 新增于:v18.2.0, v16.17.0 |
表示从获取(HTTP 或缓存)接收到的消息正文大小(以八位字节为单位),在移除任何应用的内容编码之后。
performanceResourceTiming.toJSON()
[历史]
版本 | 变更 |
---|---|
v19.0.0 | 此方法必须使用 PerformanceResourceTiming 对象作为接收者来调用。 |
v18.2.0, v16.17.0 | 新增于:v18.2.0, v16.17.0 |
返回一个 object
,它是 PerformanceResourceTiming
对象的 JSON 表示。
类: PerformanceObserver
新增于: v8.5.0
PerformanceObserver.supportedEntryTypes
新增于: v16.0.0
获取支持的类型。
new PerformanceObserver(callback)
[历史]
版本 | 变更 |
---|---|
v18.0.0 | 将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK 。 |
v8.5.0 | 新增于: v8.5.0 |
callback
<Function>list
<PerformanceObserverEntryList>observer
<PerformanceObserver>
PerformanceObserver
对象在新的 PerformanceEntry
实例被添加到性能时间线时提供通知。
import { performance, PerformanceObserver } from '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')
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()
新增于:v8.5.0
断开 PerformanceObserver
实例与所有通知的连接。
performanceObserver.observe(options)
[历史记录]
版本 | 变更 |
---|---|
v16.7.0 | 更新为符合 Performance Timeline Level 2。已添加回 buffered 选项。 |
v16.0.0 | 更新为符合 User Timing Level 3。已移除 buffered 选项。 |
v8.5.0 | 新增于:v8.5.0 |
options
<对象>type
<字符串> 单个 <PerformanceEntry> 类型。如果已指定entryTypes
,则不得给出此值。entryTypes
<字符串数组> 一个字符串数组,用于标识观察者感兴趣的 <PerformanceEntry> 实例的类型。如果未提供,则会抛出错误。buffered
<布尔值> 如果为 true,则使用全局缓冲的PerformanceEntry
列表调用观察者回调函数。如果为 false,则只有时间点之后创建的PerformanceEntry
会发送到观察者回调函数。默认值:false
。
订阅 <PerformanceObserver> 实例以接收由 options.entryTypes
或 options.type
标识的新 <PerformanceEntry> 实例的通知:
import { performance, PerformanceObserver } from 'node:perf_hooks'
const obs = new PerformanceObserver((list, observer) => {
// 异步调用一次。`list` 包含三个项目。
})
obs.observe({ type: 'mark' })
for (let n = 0; n < 3; n++) performance.mark(`test${n}`)
const { performance, PerformanceObserver } = require('node:perf_hooks')
const obs = new PerformanceObserver((list, observer) => {
// 异步调用一次。`list` 包含三个项目。
})
obs.observe({ type: 'mark' })
for (let n = 0; n < 3; n++) performance.mark(`test${n}`)
performanceObserver.takeRecords()
新增于:v16.0.0
- 返回值:<PerformanceEntry[]> 性能观察器中存储的条目列表,清空列表后返回。
类:PerformanceObserverEntryList
新增于:v8.5.0
PerformanceObserverEntryList
类用于访问传递给 PerformanceObserver
的 PerformanceEntry
实例。此类的构造函数对用户不可见。
performanceObserverEntryList.getEntries()
新增于:v8.5.0
按 performanceEntry.startTime
的时间顺序返回 PerformanceEntry
对象列表。
import { performance, PerformanceObserver } from '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')
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])
新增于: v8.5.0
name
<string>type
<string>- 返回值: <PerformanceEntry[]>
返回一个 PerformanceEntry
对象列表,这些对象按照 performanceEntry.startTime
的时间顺序排列,其 performanceEntry.name
等于 name
,并且可选地,其 performanceEntry.entryType
等于 type
。
import { performance, PerformanceObserver } from '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')
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)
新增于:v8.5.0
type
<string>- 返回值:<PerformanceEntry[]>
返回一个 PerformanceEntry
对象列表,这些对象按照 performanceEntry.startTime
的时间顺序排列,并且它们的 performanceEntry.entryType
等于 type
。
import { performance, PerformanceObserver } from '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')
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])
新增于: v15.9.0, v14.18.0
options
<Object>
返回一个 <RecordableHistogram>。
perf_hooks.monitorEventLoopDelay([options])
新增于: v11.10.0
options
<对象>resolution
<数字> 采样率(毫秒)。必须大于零。默认值:10
。
返回值: <IntervalHistogram>
此属性是 Node.js 的扩展。在 Web 浏览器中不可用。
创建一个 IntervalHistogram
对象,用于采样和报告一段时间内的事件循环延迟。延迟将以纳秒为单位报告。
使用计时器检测事件循环的近似延迟之所以有效,是因为计时器的执行与 libuv 事件循环的生命周期特别相关。也就是说,循环中的延迟会导致计时器执行延迟,而此 API 正是用于检测这些延迟。
import { monitorEventLoopDelay } from 'node:perf_hooks'
const h = monitorEventLoopDelay({ resolution: 20 })
h.enable()
// 执行某些操作。
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))
const { monitorEventLoopDelay } = require('node:perf_hooks')
const h = monitorEventLoopDelay({ resolution: 20 })
h.enable()
// 执行某些操作。
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
新增于: v11.10.0
histogram.count
新增于: v17.4.0, v16.14.0
直方图记录的样本数量。
histogram.countBigInt
新增于: v17.4.0, v16.14.0
直方图记录的样本数量。
histogram.exceeds
新增于: v11.10.0
事件循环延迟超过最大 1 小时事件循环延迟阈值的次数。
histogram.exceedsBigInt
新增于: v17.4.0, v16.14.0
事件循环延迟超过最大 1 小时事件循环延迟阈值的次数。
histogram.max
新增于: v11.10.0
记录的最大事件循环延迟。
histogram.maxBigInt
新增于:v17.4.0, v16.14.0
记录的最大事件循环延迟。
histogram.mean
新增于:v11.10.0
记录的事件循环延迟的平均值。
histogram.min
新增于:v11.10.0
记录的最小事件循环延迟。
histogram.minBigInt
新增于:v17.4.0, v16.14.0
记录的最小事件循环延迟。
histogram.percentile(percentile)
新增于:v11.10.0
返回给定百分位数的值。
histogram.percentileBigInt(percentile)
新增于: v17.4.0, v16.14.0
返回给定百分位数的值。
histogram.percentiles
新增于: v11.10.0
返回一个 Map
对象,详细说明累积的百分位数分布。
histogram.percentilesBigInt
新增于: v17.4.0, v16.14.0
返回一个 Map
对象,详细说明累积的百分位数分布。
histogram.reset()
新增于: v11.10.0
重置已收集的直方图数据。
histogram.stddev
新增于: v11.10.0
记录的事件循环延迟的标准差。
类: IntervalHistogram extends Histogram
一个在给定时间间隔内定期更新的 Histogram
。
histogram.disable()
新增于: v11.10.0
- 返回值: <boolean>
禁用更新间隔计时器。如果计时器已停止,则返回 true
;如果计时器已停止,则返回 false
。
histogram.enable()
新增于: v11.10.0
- 返回值: <boolean>
启用更新间隔计时器。如果计时器已启动,则返回 true
;如果计时器已启动,则返回 false
。
克隆 IntervalHistogram
<IntervalHistogram> 实例可以通过 <MessagePort> 进行克隆。在接收端,直方图被克隆为一个普通的 <Histogram> 对象,它不实现 enable()
和 disable()
方法。
类: RecordableHistogram extends Histogram
新增于: v15.9.0, v14.18.0
histogram.add(other)
新增于: v17.4.0, v16.14.0
other
<RecordableHistogram>
将 other
中的值添加到此直方图。
histogram.record(val)
新增于: v15.9.0, v14.18.0
histogram.recordDelta()
新增于: v15.9.0, v14.18.0
计算自上次调用 recordDelta()
以来经过的时间量(以纳秒为单位),并将该时间量记录到直方图中。
示例
测量异步操作的持续时间
以下示例使用 异步钩子 和性能 API 来测量超时操作的实际持续时间(包括执行回调所花费的时间)。
import { createHook } from 'node:async_hooks'
import { performance, PerformanceObserver } from 'node:perf_hooks'
const set = new Set()
const hook = 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)
'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()
操作加载依赖项的持续时间:
import { performance, PerformanceObserver } from 'node:perf_hooks'
// 激活观察器
const obs = new PerformanceObserver(list => {
const entries = list.getEntries()
entries.forEach(entry => {
console.log(`import('${entry[0]}')`, entry.duration)
})
performance.clearMarks()
performance.clearMeasures()
obs.disconnect()
})
obs.observe({ entryTypes: ['function'], buffered: true })
const timedImport = performance.timerify(async module => {
return await import(module)
})
await timedImport('some-module')
'use strict'
const { performance, PerformanceObserver } = require('node:perf_hooks')
const mod = require('node:module')
// 猴子补丁 require 函数
mod.Module.prototype.require = performance.timerify(mod.Module.prototype.require)
require = performance.timerify(require)
// 激活观察器
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 请求,这意味着从收到请求到发送响应的时间间隔:
import { PerformanceObserver } from 'node:perf_hooks'
import { createServer, get } from 'node:http'
const obs = new PerformanceObserver(items => {
items.getEntries().forEach(item => {
console.log(item)
})
})
obs.observe({ entryTypes: ['http'] })
const PORT = 8080
createServer((req, res) => {
res.end('ok')
}).listen(PORT, () => {
get(`http://127.0.0.1:${PORT}`)
})
'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) 连接成功所需时间
import { PerformanceObserver } from 'node:perf_hooks'
import { connect, createServer } from 'node:net'
const obs = new PerformanceObserver(items => {
items.getEntries().forEach(item => {
console.log(item)
})
})
obs.observe({ entryTypes: ['net'] })
const PORT = 8080
createServer(socket => {
socket.destroy()
}).listen(PORT, () => {
connect(PORT)
})
'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 请求成功所需时间
import { PerformanceObserver } from 'node:perf_hooks'
import { lookup, promises } from 'node:dns'
const obs = new PerformanceObserver(items => {
items.getEntries().forEach(item => {
console.log(item)
})
})
obs.observe({ entryTypes: ['dns'] })
lookup('localhost', () => {})
promises.resolve('localhost')
'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')