UNPKG

20.9 kBTypeScriptView Raw
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 */
31declare 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 }
401 | {
402 type: EntryType;
403 }
404 ): void;
405 }
406 namespace constants {
407 const NODE_PERFORMANCE_GC_MAJOR: number;
408 const NODE_PERFORMANCE_GC_MINOR: number;
409 const NODE_PERFORMANCE_GC_INCREMENTAL: number;
410 const NODE_PERFORMANCE_GC_WEAKCB: number;
411 const NODE_PERFORMANCE_GC_FLAGS_NO: number;
412 const NODE_PERFORMANCE_GC_FLAGS_CONSTRUCT_RETAINED: number;
413 const NODE_PERFORMANCE_GC_FLAGS_FORCED: number;
414 const NODE_PERFORMANCE_GC_FLAGS_SYNCHRONOUS_PHANTOM_PROCESSING: number;
415 const NODE_PERFORMANCE_GC_FLAGS_ALL_AVAILABLE_GARBAGE: number;
416 const NODE_PERFORMANCE_GC_FLAGS_ALL_EXTERNAL_MEMORY: number;
417 const NODE_PERFORMANCE_GC_FLAGS_SCHEDULE_IDLE: number;
418 }
419 const performance: Performance;
420 interface EventLoopMonitorOptions {
421 /**
422 * The sampling rate in milliseconds.
423 * Must be greater than zero.
424 * @default 10
425 */
426 resolution?: number | undefined;
427 }
428 interface Histogram {
429 /**
430 * Returns a `Map` object detailing the accumulated percentile distribution.
431 * @since v11.10.0
432 */
433 readonly percentiles: Map<number, number>;
434 /**
435 * The number of times the event loop delay exceeded the maximum 1 hour event
436 * loop delay threshold.
437 * @since v11.10.0
438 */
439 readonly exceeds: number;
440 /**
441 * The minimum recorded event loop delay.
442 * @since v11.10.0
443 */
444 readonly min: number;
445 /**
446 * The maximum recorded event loop delay.
447 * @since v11.10.0
448 */
449 readonly max: number;
450 /**
451 * The mean of the recorded event loop delays.
452 * @since v11.10.0
453 */
454 readonly mean: number;
455 /**
456 * The standard deviation of the recorded event loop delays.
457 * @since v11.10.0
458 */
459 readonly stddev: number;
460 /**
461 * Resets the collected histogram data.
462 * @since v11.10.0
463 */
464 reset(): void;
465 /**
466 * Returns the value at the given percentile.
467 * @since v11.10.0
468 * @param percentile A percentile value in the range (0, 100].
469 */
470 percentile(percentile: number): number;
471 }
472 interface IntervalHistogram extends Histogram {
473 /**
474 * Enables the update interval timer. Returns `true` if the timer was
475 * started, `false` if it was already started.
476 * @since v11.10.0
477 */
478 enable(): boolean;
479 /**
480 * Disables the update interval timer. Returns `true` if the timer was
481 * stopped, `false` if it was already stopped.
482 * @since v11.10.0
483 */
484 disable(): boolean;
485 }
486 interface RecordableHistogram extends Histogram {
487 /**
488 * @since v15.9.0, v14.18.0
489 * @param val The amount to record in the histogram.
490 */
491 record(val: number | bigint): void;
492 /**
493 * Calculates the amount of time (in nanoseconds) that has passed since the
494 * previous call to `recordDelta()` and records that amount in the histogram.
495 *
496 * ## Examples
497 * @since v15.9.0, v14.18.0
498 */
499 recordDelta(): void;
500 }
501 /**
502 * _This property is an extension by Node.js. It is not available in Web browsers._
503 *
504 * Creates an `IntervalHistogram` object that samples and reports the event loop
505 * delay over time. The delays will be reported in nanoseconds.
506 *
507 * Using a timer to detect approximate event loop delay works because the
508 * execution of timers is tied specifically to the lifecycle of the libuv
509 * event loop. That is, a delay in the loop will cause a delay in the execution
510 * of the timer, and those delays are specifically what this API is intended to
511 * detect.
512 *
513 * ```js
514 * const { monitorEventLoopDelay } = require('perf_hooks');
515 * const h = monitorEventLoopDelay({ resolution: 20 });
516 * h.enable();
517 * // Do something.
518 * h.disable();
519 * console.log(h.min);
520 * console.log(h.max);
521 * console.log(h.mean);
522 * console.log(h.stddev);
523 * console.log(h.percentiles);
524 * console.log(h.percentile(50));
525 * console.log(h.percentile(99));
526 * ```
527 * @since v11.10.0
528 */
529 function monitorEventLoopDelay(options?: EventLoopMonitorOptions): IntervalHistogram;
530 interface CreateHistogramOptions {
531 /**
532 * The minimum recordable value. Must be an integer value greater than 0.
533 * @default 1
534 */
535 min?: number | bigint | undefined;
536 /**
537 * The maximum recordable value. Must be an integer value greater than min.
538 * @default Number.MAX_SAFE_INTEGER
539 */
540 max?: number | bigint | undefined;
541 /**
542 * The number of accuracy digits. Must be a number between 1 and 5.
543 * @default 3
544 */
545 figures?: number | undefined;
546 }
547 /**
548 * Returns a `RecordableHistogram`.
549 * @since v15.9.0, v14.18.0
550 */
551 function createHistogram(options?: CreateHistogramOptions): RecordableHistogram;
552}
553declare module 'node:perf_hooks' {
554 export * from 'perf_hooks';
555}
556
\No newline at end of file