1 | /**
|
2 | * This module provides an implementation of a subset of the W3C [Web Performance APIs](https://w3c.github.io/perf-timing-primer/) as well as additional APIs for
|
3 | * Node.js-specific performance measurements.
|
4 | *
|
5 | * Node.js supports the following [Web Performance APIs](https://w3c.github.io/perf-timing-primer/):
|
6 | *
|
7 | * * [High Resolution Time](https://www.w3.org/TR/hr-time-2)
|
8 | * * [Performance Timeline](https://w3c.github.io/performance-timeline/)
|
9 | * * [User Timing](https://www.w3.org/TR/user-timing/)
|
10 | *
|
11 | * ```js
|
12 | * const { PerformanceObserver, performance } = require('perf_hooks');
|
13 | *
|
14 | * const obs = new PerformanceObserver((items) => {
|
15 | * console.log(items.getEntries()[0].duration);
|
16 | * performance.clearMarks();
|
17 | * });
|
18 | * obs.observe({ type: 'measure' });
|
19 | * performance.measure('Start to Now');
|
20 | *
|
21 | * performance.mark('A');
|
22 | * doSomeLongRunningProcess(() => {
|
23 | * performance.measure('A to Now', 'A');
|
24 | *
|
25 | * performance.mark('B');
|
26 | * performance.measure('A to B', 'A', 'B');
|
27 | * });
|
28 | * ```
|
29 | * @see [source](https://github.com/nodejs/node/blob/v17.0.0/lib/perf_hooks.js)
|
30 | */
|
31 | declare module 'perf_hooks' {
|
32 | import { AsyncResource } from 'node:async_hooks';
|
33 | type EntryType = 'node' | 'mark' | 'measure' | 'gc' | 'function' | 'http2' | 'http';
|
34 | interface NodeGCPerformanceDetail {
|
35 | /**
|
36 | * When `performanceEntry.entryType` is equal to 'gc', `the performance.kind` property identifies
|
37 | * the type of garbage collection operation that occurred.
|
38 | * See perf_hooks.constants for valid values.
|
39 | */
|
40 | readonly kind?: number | undefined;
|
41 | /**
|
42 | * When `performanceEntry.entryType` is equal to 'gc', the `performance.flags`
|
43 | * property contains additional information about garbage collection operation.
|
44 | * See perf_hooks.constants for valid values.
|
45 | */
|
46 | readonly flags?: number | undefined;
|
47 | }
|
48 | /**
|
49 | * @since v8.5.0
|
50 | */
|
51 | class PerformanceEntry {
|
52 | protected constructor();
|
53 | /**
|
54 | * The total number of milliseconds elapsed for this entry. This value will not
|
55 | * be meaningful for all Performance Entry types.
|
56 | * @since v8.5.0
|
57 | */
|
58 | readonly duration: number;
|
59 | /**
|
60 | * The name of the performance entry.
|
61 | * @since v8.5.0
|
62 | */
|
63 | readonly name: string;
|
64 | /**
|
65 | * The high resolution millisecond timestamp marking the starting time of the
|
66 | * Performance Entry.
|
67 | * @since v8.5.0
|
68 | */
|
69 | readonly startTime: number;
|
70 | /**
|
71 | * The type of the performance entry. It may be one of:
|
72 | *
|
73 | * * `'node'` (Node.js only)
|
74 | * * `'mark'` (available on the Web)
|
75 | * * `'measure'` (available on the Web)
|
76 | * * `'gc'` (Node.js only)
|
77 | * * `'function'` (Node.js only)
|
78 | * * `'http2'` (Node.js only)
|
79 | * * `'http'` (Node.js only)
|
80 | * @since v8.5.0
|
81 | */
|
82 | readonly entryType: EntryType;
|
83 | /**
|
84 | * Additional detail specific to the `entryType`.
|
85 | * @since v16.0.0
|
86 | */
|
87 | readonly detail?: NodeGCPerformanceDetail | unknown | undefined; // TODO: Narrow this based on entry type.
|
88 | }
|
89 | /**
|
90 | * _This property is an extension by Node.js. It is not available in Web browsers._
|
91 | *
|
92 | * Provides timing details for Node.js itself. The constructor of this class
|
93 | * is not exposed to users.
|
94 | * @since v8.5.0
|
95 | */
|
96 | class PerformanceNodeTiming extends PerformanceEntry {
|
97 | /**
|
98 | * The high resolution millisecond timestamp at which the Node.js process
|
99 | * completed bootstrapping. If bootstrapping has not yet finished, the property
|
100 | * has the value of -1.
|
101 | * @since v8.5.0
|
102 | */
|
103 | readonly bootstrapComplete: number;
|
104 | /**
|
105 | * The high resolution millisecond timestamp at which the Node.js environment was
|
106 | * initialized.
|
107 | * @since v8.5.0
|
108 | */
|
109 | readonly environment: number;
|
110 | /**
|
111 | * The high resolution millisecond timestamp of the amount of time the event loop
|
112 | * has been idle within the event loop's event provider (e.g. `epoll_wait`). This
|
113 | * does not take CPU usage into consideration. If the event loop has not yet
|
114 | * started (e.g., in the first tick of the main script), the property has the
|
115 | * value of 0.
|
116 | * @since v14.10.0, v12.19.0
|
117 | */
|
118 | readonly idleTime: number;
|
119 | /**
|
120 | * The high resolution millisecond timestamp at which the Node.js event loop
|
121 | * exited. If the event loop has not yet exited, the property has the value of -1\.
|
122 | * It can only have a value of not -1 in a handler of the `'exit'` event.
|
123 | * @since v8.5.0
|
124 | */
|
125 | readonly loopExit: number;
|
126 | /**
|
127 | * The high resolution millisecond timestamp at which the Node.js event loop
|
128 | * started. If the event loop has not yet started (e.g., in the first tick of the
|
129 | * main script), the property has the value of -1.
|
130 | * @since v8.5.0
|
131 | */
|
132 | readonly loopStart: number;
|
133 | /**
|
134 | * The high resolution millisecond timestamp at which the V8 platform was
|
135 | * initialized.
|
136 | * @since v8.5.0
|
137 | */
|
138 | readonly v8Start: number;
|
139 | }
|
140 | interface EventLoopUtilization {
|
141 | idle: number;
|
142 | active: number;
|
143 | utilization: number;
|
144 | }
|
145 | /**
|
146 | * @param util1 The result of a previous call to eventLoopUtilization()
|
147 | * @param util2 The result of a previous call to eventLoopUtilization() prior to util1
|
148 | */
|
149 | type EventLoopUtilityFunction = (util1?: EventLoopUtilization, util2?: EventLoopUtilization) => EventLoopUtilization;
|
150 | interface MarkOptions {
|
151 | /**
|
152 | * Additional optional detail to include with the mark.
|
153 | */
|
154 | detail?: unknown | undefined;
|
155 | /**
|
156 | * An optional timestamp to be used as the mark time.
|
157 | * @default `performance.now()`.
|
158 | */
|
159 | startTime?: number | undefined;
|
160 | }
|
161 | interface MeasureOptions {
|
162 | /**
|
163 | * Additional optional detail to include with the mark.
|
164 | */
|
165 | detail?: unknown | undefined;
|
166 | /**
|
167 | * Duration between start and end times.
|
168 | */
|
169 | duration?: number | undefined;
|
170 | /**
|
171 | * Timestamp to be used as the end time, or a string identifying a previously recorded mark.
|
172 | */
|
173 | end?: number | string | undefined;
|
174 | /**
|
175 | * Timestamp to be used as the start time, or a string identifying a previously recorded mark.
|
176 | */
|
177 | start?: number | string | undefined;
|
178 | }
|
179 | interface TimerifyOptions {
|
180 | /**
|
181 | * A histogram object created using
|
182 | * `perf_hooks.createHistogram()` that will record runtime durations in
|
183 | * nanoseconds.
|
184 | */
|
185 | histogram?: RecordableHistogram | undefined;
|
186 | }
|
187 | interface Performance {
|
188 | /**
|
189 | * If name is not provided, removes all PerformanceMark objects from the Performance Timeline.
|
190 | * If name is provided, removes only the named mark.
|
191 | * @param name
|
192 | */
|
193 | clearMarks(name?: string): void;
|
194 | /**
|
195 | * Creates a new PerformanceMark entry in the Performance Timeline.
|
196 | * A PerformanceMark is a subclass of PerformanceEntry whose performanceEntry.entryType is always 'mark',
|
197 | * and whose performanceEntry.duration is always 0.
|
198 | * Performance marks are used to mark specific significant moments in the Performance Timeline.
|
199 | * @param name
|
200 | */
|
201 | mark(name?: string, options?: MarkOptions): void;
|
202 | /**
|
203 | * Creates a new PerformanceMeasure entry in the Performance Timeline.
|
204 | * A PerformanceMeasure is a subclass of PerformanceEntry whose performanceEntry.entryType is always 'measure',
|
205 | * and whose performanceEntry.duration measures the number of milliseconds elapsed since startMark and endMark.
|
206 | *
|
207 | * The startMark argument may identify any existing PerformanceMark in the the Performance Timeline, or may identify
|
208 | * any of the timestamp properties provided by the PerformanceNodeTiming class. If the named startMark does not exist,
|
209 | * then startMark is set to timeOrigin by default.
|
210 | *
|
211 | * The endMark argument must identify any existing PerformanceMark in the the Performance Timeline or any of the timestamp
|
212 | * properties provided by the PerformanceNodeTiming class. If the named endMark does not exist, an error will be thrown.
|
213 | * @param name
|
214 | * @param startMark
|
215 | * @param endMark
|
216 | */
|
217 | measure(name: string, startMark?: string, endMark?: string): void;
|
218 | measure(name: string, options: MeasureOptions): void;
|
219 | /**
|
220 | * An instance of the PerformanceNodeTiming class that provides performance metrics for specific Node.js operational milestones.
|
221 | */
|
222 | readonly nodeTiming: PerformanceNodeTiming;
|
223 | /**
|
224 | * @return the current high resolution millisecond timestamp
|
225 | */
|
226 | now(): number;
|
227 | /**
|
228 | * The timeOrigin specifies the high resolution millisecond timestamp from which all performance metric durations are measured.
|
229 | */
|
230 | readonly timeOrigin: number;
|
231 | /**
|
232 | * Wraps a function within a new function that measures the running time of the wrapped function.
|
233 | * A PerformanceObserver must be subscribed to the 'function' event type in order for the timing details to be accessed.
|
234 | * @param fn
|
235 | */
|
236 | timerify<T extends (...params: any[]) => any>(fn: T, options?: TimerifyOptions): T;
|
237 | /**
|
238 | * eventLoopUtilization is similar to CPU utilization except that it is calculated using high precision wall-clock time.
|
239 | * It represents the percentage of time the event loop has spent outside the event loop's event provider (e.g. epoll_wait).
|
240 | * No other CPU idle time is taken into consideration.
|
241 | */
|
242 | eventLoopUtilization: EventLoopUtilityFunction;
|
243 | }
|
244 | interface PerformanceObserverEntryList {
|
245 | /**
|
246 | * Returns a list of `PerformanceEntry` objects in chronological order
|
247 | * with respect to `performanceEntry.startTime`.
|
248 | *
|
249 | * ```js
|
250 | * const {
|
251 | * performance,
|
252 | * PerformanceObserver
|
253 | * } = require('perf_hooks');
|
254 | *
|
255 | * const obs = new PerformanceObserver((perfObserverList, observer) => {
|
256 | * console.log(perfObserverList.getEntries());
|
257 | *
|
258 | * * [
|
259 | * * PerformanceEntry {
|
260 | * * name: 'test',
|
261 | * * entryType: 'mark',
|
262 | * * startTime: 81.465639,
|
263 | * * duration: 0
|
264 | * * },
|
265 | * * PerformanceEntry {
|
266 | * * name: 'meow',
|
267 | * * entryType: 'mark',
|
268 | * * startTime: 81.860064,
|
269 | * * duration: 0
|
270 | * * }
|
271 | * * ]
|
272 | *
|
273 | * observer.disconnect();
|
274 | * });
|
275 | * obs.observe({ type: 'mark' });
|
276 | *
|
277 | * performance.mark('test');
|
278 | * performance.mark('meow');
|
279 | * ```
|
280 | * @since v8.5.0
|
281 | */
|
282 | getEntries(): PerformanceEntry[];
|
283 | /**
|
284 | * Returns a list of `PerformanceEntry` objects in chronological order
|
285 | * with respect to `performanceEntry.startTime` whose `performanceEntry.name` is
|
286 | * equal to `name`, and optionally, whose `performanceEntry.entryType` is equal to`type`.
|
287 | *
|
288 | * ```js
|
289 | * const {
|
290 | * performance,
|
291 | * PerformanceObserver
|
292 | * } = require('perf_hooks');
|
293 | *
|
294 | * const obs = new PerformanceObserver((perfObserverList, observer) => {
|
295 | * console.log(perfObserverList.getEntriesByName('meow'));
|
296 | *
|
297 | * * [
|
298 | * * PerformanceEntry {
|
299 | * * name: 'meow',
|
300 | * * entryType: 'mark',
|
301 | * * startTime: 98.545991,
|
302 | * * duration: 0
|
303 | * * }
|
304 | * * ]
|
305 | *
|
306 | * console.log(perfObserverList.getEntriesByName('nope')); // []
|
307 | *
|
308 | * console.log(perfObserverList.getEntriesByName('test', 'mark'));
|
309 | *
|
310 | * * [
|
311 | * * PerformanceEntry {
|
312 | * * name: 'test',
|
313 | * * entryType: 'mark',
|
314 | * * startTime: 63.518931,
|
315 | * * duration: 0
|
316 | * * }
|
317 | * * ]
|
318 | *
|
319 | * console.log(perfObserverList.getEntriesByName('test', 'measure')); // []
|
320 | * observer.disconnect();
|
321 | * });
|
322 | * obs.observe({ entryTypes: ['mark', 'measure'] });
|
323 | *
|
324 | * performance.mark('test');
|
325 | * performance.mark('meow');
|
326 | * ```
|
327 | * @since v8.5.0
|
328 | */
|
329 | getEntriesByName(name: string, type?: EntryType): PerformanceEntry[];
|
330 | /**
|
331 | * Returns a list of `PerformanceEntry` objects in chronological order
|
332 | * with respect to `performanceEntry.startTime` whose `performanceEntry.entryType`is equal to `type`.
|
333 | *
|
334 | * ```js
|
335 | * const {
|
336 | * performance,
|
337 | * PerformanceObserver
|
338 | * } = require('perf_hooks');
|
339 | *
|
340 | * const obs = new PerformanceObserver((perfObserverList, observer) => {
|
341 | * console.log(perfObserverList.getEntriesByType('mark'));
|
342 | *
|
343 | * * [
|
344 | * * PerformanceEntry {
|
345 | * * name: 'test',
|
346 | * * entryType: 'mark',
|
347 | * * startTime: 55.897834,
|
348 | * * duration: 0
|
349 | * * },
|
350 | * * PerformanceEntry {
|
351 | * * name: 'meow',
|
352 | * * entryType: 'mark',
|
353 | * * startTime: 56.350146,
|
354 | * * duration: 0
|
355 | * * }
|
356 | * * ]
|
357 | *
|
358 | * observer.disconnect();
|
359 | * });
|
360 | * obs.observe({ type: 'mark' });
|
361 | *
|
362 | * performance.mark('test');
|
363 | * performance.mark('meow');
|
364 | * ```
|
365 | * @since v8.5.0
|
366 | */
|
367 | getEntriesByType(type: EntryType): PerformanceEntry[];
|
368 | }
|
369 | type PerformanceObserverCallback = (list: PerformanceObserverEntryList, observer: PerformanceObserver) => void;
|
370 | class PerformanceObserver extends AsyncResource {
|
371 | constructor(callback: PerformanceObserverCallback);
|
372 | /**
|
373 | * Disconnects the `PerformanceObserver` instance from all notifications.
|
374 | * @since v8.5.0
|
375 | */
|
376 | disconnect(): void;
|
377 | /**
|
378 | * Subscribes the `PerformanceObserver` instance to notifications of new `PerformanceEntry` instances identified either by `options.entryTypes`or `options.type`:
|
379 | *
|
380 | * ```js
|
381 | * const {
|
382 | * performance,
|
383 | * PerformanceObserver
|
384 | * } = require('perf_hooks');
|
385 | *
|
386 | * const obs = new PerformanceObserver((list, observer) => {
|
387 | * // Called three times synchronously. `list` contains one item.
|
388 | * });
|
389 | * obs.observe({ type: 'mark' });
|
390 | *
|
391 | * for (let n = 0; n < 3; n++)
|
392 | * performance.mark(`test${n}`);
|
393 | * ```
|
394 | * @since v8.5.0
|
395 | */
|
396 | observe(
|
397 | options:
|
398 | | {
|
399 | entryTypes: ReadonlyArray<EntryType>;
|
400 | buffered?: boolean | undefined;
|
401 | }
|
402 | | {
|
403 | type: EntryType;
|
404 | buffered?: boolean | undefined;
|
405 | }
|
406 | ): void;
|
407 | }
|
408 | namespace constants {
|
409 | const NODE_PERFORMANCE_GC_MAJOR: number;
|
410 | const NODE_PERFORMANCE_GC_MINOR: number;
|
411 | const NODE_PERFORMANCE_GC_INCREMENTAL: number;
|
412 | const NODE_PERFORMANCE_GC_WEAKCB: number;
|
413 | const NODE_PERFORMANCE_GC_FLAGS_NO: number;
|
414 | const NODE_PERFORMANCE_GC_FLAGS_CONSTRUCT_RETAINED: number;
|
415 | const NODE_PERFORMANCE_GC_FLAGS_FORCED: number;
|
416 | const NODE_PERFORMANCE_GC_FLAGS_SYNCHRONOUS_PHANTOM_PROCESSING: number;
|
417 | const NODE_PERFORMANCE_GC_FLAGS_ALL_AVAILABLE_GARBAGE: number;
|
418 | const NODE_PERFORMANCE_GC_FLAGS_ALL_EXTERNAL_MEMORY: number;
|
419 | const NODE_PERFORMANCE_GC_FLAGS_SCHEDULE_IDLE: number;
|
420 | }
|
421 | const performance: Performance;
|
422 | interface EventLoopMonitorOptions {
|
423 | /**
|
424 | * The sampling rate in milliseconds.
|
425 | * Must be greater than zero.
|
426 | * @default 10
|
427 | */
|
428 | resolution?: number | undefined;
|
429 | }
|
430 | interface Histogram {
|
431 | /**
|
432 | * Returns a `Map` object detailing the accumulated percentile distribution.
|
433 | * @since v11.10.0
|
434 | */
|
435 | readonly percentiles: Map<number, number>;
|
436 | /**
|
437 | * The number of times the event loop delay exceeded the maximum 1 hour event
|
438 | * loop delay threshold.
|
439 | * @since v11.10.0
|
440 | */
|
441 | readonly exceeds: number;
|
442 | /**
|
443 | * The minimum recorded event loop delay.
|
444 | * @since v11.10.0
|
445 | */
|
446 | readonly min: number;
|
447 | /**
|
448 | * The maximum recorded event loop delay.
|
449 | * @since v11.10.0
|
450 | */
|
451 | readonly max: number;
|
452 | /**
|
453 | * The mean of the recorded event loop delays.
|
454 | * @since v11.10.0
|
455 | */
|
456 | readonly mean: number;
|
457 | /**
|
458 | * The standard deviation of the recorded event loop delays.
|
459 | * @since v11.10.0
|
460 | */
|
461 | readonly stddev: number;
|
462 | /**
|
463 | * Resets the collected histogram data.
|
464 | * @since v11.10.0
|
465 | */
|
466 | reset(): void;
|
467 | /**
|
468 | * Returns the value at the given percentile.
|
469 | * @since v11.10.0
|
470 | * @param percentile A percentile value in the range (0, 100].
|
471 | */
|
472 | percentile(percentile: number): number;
|
473 | }
|
474 | interface IntervalHistogram extends Histogram {
|
475 | /**
|
476 | * Enables the update interval timer. Returns `true` if the timer was
|
477 | * started, `false` if it was already started.
|
478 | * @since v11.10.0
|
479 | */
|
480 | enable(): boolean;
|
481 | /**
|
482 | * Disables the update interval timer. Returns `true` if the timer was
|
483 | * stopped, `false` if it was already stopped.
|
484 | * @since v11.10.0
|
485 | */
|
486 | disable(): boolean;
|
487 | }
|
488 | interface RecordableHistogram extends Histogram {
|
489 | /**
|
490 | * @since v15.9.0, v14.18.0
|
491 | * @param val The amount to record in the histogram.
|
492 | */
|
493 | record(val: number | bigint): void;
|
494 | /**
|
495 | * Calculates the amount of time (in nanoseconds) that has passed since the
|
496 | * previous call to `recordDelta()` and records that amount in the histogram.
|
497 | *
|
498 | * ## Examples
|
499 | * @since v15.9.0, v14.18.0
|
500 | */
|
501 | recordDelta(): void;
|
502 | }
|
503 | /**
|
504 | * _This property is an extension by Node.js. It is not available in Web browsers._
|
505 | *
|
506 | * Creates an `IntervalHistogram` object that samples and reports the event loop
|
507 | * delay over time. The delays will be reported in nanoseconds.
|
508 | *
|
509 | * Using a timer to detect approximate event loop delay works because the
|
510 | * execution of timers is tied specifically to the lifecycle of the libuv
|
511 | * event loop. That is, a delay in the loop will cause a delay in the execution
|
512 | * of the timer, and those delays are specifically what this API is intended to
|
513 | * detect.
|
514 | *
|
515 | * ```js
|
516 | * const { monitorEventLoopDelay } = require('perf_hooks');
|
517 | * const h = monitorEventLoopDelay({ resolution: 20 });
|
518 | * h.enable();
|
519 | * // Do something.
|
520 | * h.disable();
|
521 | * console.log(h.min);
|
522 | * console.log(h.max);
|
523 | * console.log(h.mean);
|
524 | * console.log(h.stddev);
|
525 | * console.log(h.percentiles);
|
526 | * console.log(h.percentile(50));
|
527 | * console.log(h.percentile(99));
|
528 | * ```
|
529 | * @since v11.10.0
|
530 | */
|
531 | function monitorEventLoopDelay(options?: EventLoopMonitorOptions): IntervalHistogram;
|
532 | interface CreateHistogramOptions {
|
533 | /**
|
534 | * The minimum recordable value. Must be an integer value greater than 0.
|
535 | * @default 1
|
536 | */
|
537 | min?: number | bigint | undefined;
|
538 | /**
|
539 | * The maximum recordable value. Must be an integer value greater than min.
|
540 | * @default Number.MAX_SAFE_INTEGER
|
541 | */
|
542 | max?: number | bigint | undefined;
|
543 | /**
|
544 | * The number of accuracy digits. Must be a number between 1 and 5.
|
545 | * @default 3
|
546 | */
|
547 | figures?: number | undefined;
|
548 | }
|
549 | /**
|
550 | * Returns a `RecordableHistogram`.
|
551 | * @since v15.9.0, v14.18.0
|
552 | */
|
553 | function createHistogram(options?: CreateHistogramOptions): RecordableHistogram;
|
554 | }
|
555 | declare module 'node:perf_hooks' {
|
556 | export * from 'perf_hooks';
|
557 | }
|
558 |
|
\ | No newline at end of file |