• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Performance measurement APIs
2
3<!--introduced_in=v8.5.0-->
4
5> Stability: 2 - Stable
6
7<!-- source_link=lib/perf_hooks.js -->
8
9This module provides an implementation of a subset of the W3C
10[Web Performance APIs][] as well as additional APIs for
11Node.js-specific performance measurements.
12
13Node.js supports the following [Web Performance APIs][]:
14
15* [High Resolution Time][]
16* [Performance Timeline][]
17* [User Timing][]
18
19```js
20const { PerformanceObserver, performance } = require('perf_hooks');
21
22const obs = new PerformanceObserver((items) => {
23  console.log(items.getEntries()[0].duration);
24  performance.clearMarks();
25});
26obs.observe({ entryTypes: ['measure'] });
27performance.measure('Start to Now');
28
29performance.mark('A');
30doSomeLongRunningProcess(() => {
31  performance.measure('A to Now', 'A');
32
33  performance.mark('B');
34  performance.measure('A to B', 'A', 'B');
35});
36```
37
38## `perf_hooks.performance`
39<!-- YAML
40added: v8.5.0
41-->
42
43An object that can be used to collect performance metrics from the current
44Node.js instance. It is similar to [`window.performance`][] in browsers.
45
46### `performance.clearMarks([name])`
47<!-- YAML
48added: v8.5.0
49-->
50
51* `name` {string}
52
53If `name` is not provided, removes all `PerformanceMark` objects from the
54Performance Timeline. If `name` is provided, removes only the named mark.
55
56### `performance.eventLoopUtilization([utilization1[, utilization2]])`
57<!-- YAML
58added:
59 - v14.10.0
60 - v12.19.0
61-->
62
63* `utilization1` {Object} The result of a previous call to
64    `eventLoopUtilization()`.
65* `utilization2` {Object} The result of a previous call to
66    `eventLoopUtilization()` prior to `utilization1`.
67* Returns {Object}
68  * `idle` {number}
69  * `active` {number}
70  * `utilization` {number}
71
72The `eventLoopUtilization()` method returns an object that contains the
73cumulative duration of time the event loop has been both idle and active as a
74high resolution milliseconds timer. The `utilization` value is the calculated
75Event Loop Utilization (ELU).
76
77If bootstrapping has not yet finished on the main thread the properties have
78the value of `0`. The ELU is immediately available on [Worker threads][] since
79bootstrap happens within the event loop.
80
81Both `utilization1` and `utilization2` are optional parameters.
82
83If `utilization1` is passed, then the delta between the current call's `active`
84and `idle` times, as well as the corresponding `utilization` value are
85calculated and returned (similar to [`process.hrtime()`][]).
86
87If `utilization1` and `utilization2` are both passed, then the delta is
88calculated between the two arguments. This is a convenience option because,
89unlike [`process.hrtime()`][], calculating the ELU is more complex than a
90single subtraction.
91
92ELU is similar to CPU utilization, except that it only measures event loop
93statistics and not CPU usage. It represents the percentage of time the event
94loop has spent outside the event loop's event provider (e.g. `epoll_wait`).
95No other CPU idle time is taken into consideration. The following is an example
96of how a mostly idle process will have a high ELU.
97
98```js
99'use strict';
100const { eventLoopUtilization } = require('perf_hooks').performance;
101const { spawnSync } = require('child_process');
102
103setImmediate(() => {
104  const elu = eventLoopUtilization();
105  spawnSync('sleep', ['5']);
106  console.log(eventLoopUtilization(elu).utilization);
107});
108```
109
110Although the CPU is mostly idle while running this script, the value of
111`utilization` is `1`. This is because the call to
112[`child_process.spawnSync()`][] blocks the event loop from proceeding.
113
114Passing in a user-defined object instead of the result of a previous call to
115`eventLoopUtilization()` will lead to undefined behavior. The return values
116are not guaranteed to reflect any correct state of the event loop.
117
118### `performance.mark([name])`
119<!-- YAML
120added: v8.5.0
121-->
122
123* `name` {string}
124
125Creates a new `PerformanceMark` entry in the Performance Timeline. A
126`PerformanceMark` is a subclass of `PerformanceEntry` whose
127`performanceEntry.entryType` is always `'mark'`, and whose
128`performanceEntry.duration` is always `0`. Performance marks are used
129to mark specific significant moments in the Performance Timeline.
130
131### `performance.measure(name[, startMark[, endMark]])`
132<!-- YAML
133added: v8.5.0
134changes:
135  - version: v14.0.0
136    pr-url: https://github.com/nodejs/node/pull/32651
137    description: Make `startMark` and `endMark` parameters optional.
138-->
139
140* `name` {string}
141* `startMark` {string} Optional.
142* `endMark` {string} Optional.
143
144Creates a new `PerformanceMeasure` entry in the Performance Timeline. A
145`PerformanceMeasure` is a subclass of `PerformanceEntry` whose
146`performanceEntry.entryType` is always `'measure'`, and whose
147`performanceEntry.duration` measures the number of milliseconds elapsed since
148`startMark` and `endMark`.
149
150The `startMark` argument may identify any *existing* `PerformanceMark` in the
151Performance Timeline, or *may* identify any of the timestamp properties
152provided by the `PerformanceNodeTiming` class. If the named `startMark` does
153not exist, then `startMark` is set to [`timeOrigin`][] by default.
154
155The optional `endMark` argument must identify any *existing* `PerformanceMark`
156in the Performance Timeline or any of the timestamp properties provided by the
157`PerformanceNodeTiming` class. `endMark` will be `performance.now()`
158if no parameter is passed, otherwise if the named `endMark` does not exist, an
159error will be thrown.
160
161### `performance.nodeTiming`
162<!-- YAML
163added: v8.5.0
164-->
165
166* {PerformanceNodeTiming}
167
168_This property is an extension by Node.js. It is not available in Web browsers._
169
170An instance of the `PerformanceNodeTiming` class that provides performance
171metrics for specific Node.js operational milestones.
172
173### `performance.now()`
174<!-- YAML
175added: v8.5.0
176-->
177
178* Returns: {number}
179
180Returns the current high resolution millisecond timestamp, where 0 represents
181the start of the current `node` process.
182
183### `performance.timeOrigin`
184<!-- YAML
185added: v8.5.0
186-->
187
188* {number}
189
190The [`timeOrigin`][] specifies the high resolution millisecond timestamp at
191which the current `node` process began, measured in Unix time.
192
193### `performance.timerify(fn)`
194<!-- YAML
195added: v8.5.0
196-->
197
198* `fn` {Function}
199
200_This property is an extension by Node.js. It is not available in Web browsers._
201
202Wraps a function within a new function that measures the running time of the
203wrapped function. A `PerformanceObserver` must be subscribed to the `'function'`
204event type in order for the timing details to be accessed.
205
206```js
207const {
208  performance,
209  PerformanceObserver
210} = require('perf_hooks');
211
212function someFunction() {
213  console.log('hello world');
214}
215
216const wrapped = performance.timerify(someFunction);
217
218const obs = new PerformanceObserver((list) => {
219  console.log(list.getEntries()[0].duration);
220  obs.disconnect();
221});
222obs.observe({ entryTypes: ['function'] });
223
224// A performance timeline entry will be created
225wrapped();
226```
227
228## Class: `PerformanceEntry`
229<!-- YAML
230added: v8.5.0
231-->
232
233### `performanceEntry.duration`
234<!-- YAML
235added: v8.5.0
236-->
237
238* {number}
239
240The total number of milliseconds elapsed for this entry. This value will not
241be meaningful for all Performance Entry types.
242
243### `performanceEntry.entryType`
244<!-- YAML
245added: v8.5.0
246-->
247
248* {string}
249
250The type of the performance entry. It may be one of:
251
252* `'node'` (Node.js only)
253* `'mark'` (available on the Web)
254* `'measure'` (available on the Web)
255* `'gc'` (Node.js only)
256* `'function'` (Node.js only)
257* `'http2'` (Node.js only)
258* `'http'` (Node.js only)
259
260### `performanceEntry.flags`
261<!-- YAML
262added:
263 - v13.9.0
264 - v12.17.0
265-->
266
267* {number}
268
269_This property is an extension by Node.js. It is not available in Web browsers._
270
271When `performanceEntry.entryType` is equal to `'gc'`, the `performance.flags`
272property contains additional information about garbage collection operation.
273The value may be one of:
274
275* `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_NO`
276* `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_CONSTRUCT_RETAINED`
277* `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_FORCED`
278* `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_SYNCHRONOUS_PHANTOM_PROCESSING`
279* `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_ALL_AVAILABLE_GARBAGE`
280* `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_ALL_EXTERNAL_MEMORY`
281* `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_SCHEDULE_IDLE`
282
283### `performanceEntry.name`
284<!-- YAML
285added: v8.5.0
286-->
287
288* {string}
289
290The name of the performance entry.
291
292### `performanceEntry.kind`
293<!-- YAML
294added: v8.5.0
295-->
296
297* {number}
298
299_This property is an extension by Node.js. It is not available in Web browsers._
300
301When `performanceEntry.entryType` is equal to `'gc'`, the `performance.kind`
302property identifies the type of garbage collection operation that occurred.
303The value may be one of:
304
305* `perf_hooks.constants.NODE_PERFORMANCE_GC_MAJOR`
306* `perf_hooks.constants.NODE_PERFORMANCE_GC_MINOR`
307* `perf_hooks.constants.NODE_PERFORMANCE_GC_INCREMENTAL`
308* `perf_hooks.constants.NODE_PERFORMANCE_GC_WEAKCB`
309
310### `performanceEntry.startTime`
311<!-- YAML
312added: v8.5.0
313-->
314
315* {number}
316
317The high resolution millisecond timestamp marking the starting time of the
318Performance Entry.
319
320## Class: `PerformanceNodeTiming`
321<!-- YAML
322added: v8.5.0
323-->
324
325* Extends: {PerformanceEntry}
326
327_This property is an extension by Node.js. It is not available in Web browsers._
328
329Provides timing details for Node.js itself. The constructor of this class
330is not exposed to users.
331
332### `performanceNodeTiming.bootstrapComplete`
333<!-- YAML
334added: v8.5.0
335-->
336
337* {number}
338
339The high resolution millisecond timestamp at which the Node.js process
340completed bootstrapping. If bootstrapping has not yet finished, the property
341has the value of -1.
342
343### `performanceNodeTiming.environment`
344<!-- YAML
345added: v8.5.0
346-->
347
348* {number}
349
350The high resolution millisecond timestamp at which the Node.js environment was
351initialized.
352
353### `performanceNodeTiming.idleTime`
354<!-- YAML
355added:
356  - v14.10.0
357  - v12.19.0
358-->
359
360* {number}
361
362The high resolution millisecond timestamp of the amount of time the event loop
363has been idle within the event loop's event provider (e.g. `epoll_wait`). This
364does not take CPU usage into consideration. If the event loop has not yet
365started (e.g., in the first tick of the main script), the property has the
366value of 0.
367
368### `performanceNodeTiming.loopExit`
369<!-- YAML
370added: v8.5.0
371-->
372
373* {number}
374
375The high resolution millisecond timestamp at which the Node.js event loop
376exited. If the event loop has not yet exited, the property has the value of -1.
377It can only have a value of not -1 in a handler of the [`'exit'`][] event.
378
379### `performanceNodeTiming.loopStart`
380<!-- YAML
381added: v8.5.0
382-->
383
384* {number}
385
386The high resolution millisecond timestamp at which the Node.js event loop
387started. If the event loop has not yet started (e.g., in the first tick of the
388main script), the property has the value of -1.
389
390### `performanceNodeTiming.nodeStart`
391<!-- YAML
392added: v8.5.0
393-->
394
395* {number}
396
397The high resolution millisecond timestamp at which the Node.js process was
398initialized.
399
400### `performanceNodeTiming.v8Start`
401<!-- YAML
402added: v8.5.0
403-->
404
405* {number}
406
407The high resolution millisecond timestamp at which the V8 platform was
408initialized.
409
410## Class: `perf_hooks.PerformanceObserver`
411
412### `new PerformanceObserver(callback)`
413<!-- YAML
414added: v8.5.0
415-->
416
417* `callback` {Function}
418  * `list` {PerformanceObserverEntryList}
419  * `observer` {PerformanceObserver}
420
421`PerformanceObserver` objects provide notifications when new
422`PerformanceEntry` instances have been added to the Performance Timeline.
423
424```js
425const {
426  performance,
427  PerformanceObserver
428} = require('perf_hooks');
429
430const obs = new PerformanceObserver((list, observer) => {
431  console.log(list.getEntries());
432  observer.disconnect();
433});
434obs.observe({ entryTypes: ['mark'], buffered: true });
435
436performance.mark('test');
437```
438
439Because `PerformanceObserver` instances introduce their own additional
440performance overhead, instances should not be left subscribed to notifications
441indefinitely. Users should disconnect observers as soon as they are no
442longer needed.
443
444The `callback` is invoked when a `PerformanceObserver` is
445notified about new `PerformanceEntry` instances. The callback receives a
446`PerformanceObserverEntryList` instance and a reference to the
447`PerformanceObserver`.
448
449### `performanceObserver.disconnect()`
450<!-- YAML
451added: v8.5.0
452-->
453Disconnects the `PerformanceObserver` instance from all notifications.
454
455### `performanceObserver.observe(options)`
456<!-- YAML
457added: v8.5.0
458-->
459
460* `options` {Object}
461  * `entryTypes` {string[]} An array of strings identifying the types of
462    `PerformanceEntry` instances the observer is interested in. If not
463    provided an error will be thrown.
464  * `buffered` {boolean} If true, the notification callback will be
465    called using `setImmediate()` and multiple `PerformanceEntry` instance
466    notifications will be buffered internally. If `false`, notifications will
467    be immediate and synchronous. **Default:** `false`.
468
469Subscribes the `PerformanceObserver` instance to notifications of new
470`PerformanceEntry` instances identified by `options.entryTypes`.
471
472When `options.buffered` is `false`, the `callback` will be invoked once for
473every `PerformanceEntry` instance:
474
475```js
476const {
477  performance,
478  PerformanceObserver
479} = require('perf_hooks');
480
481const obs = new PerformanceObserver((list, observer) => {
482  // Called three times synchronously. `list` contains one item.
483});
484obs.observe({ entryTypes: ['mark'] });
485
486for (let n = 0; n < 3; n++)
487  performance.mark(`test${n}`);
488```
489
490```js
491const {
492  performance,
493  PerformanceObserver
494} = require('perf_hooks');
495
496const obs = new PerformanceObserver((list, observer) => {
497  // Called once. `list` contains three items.
498});
499obs.observe({ entryTypes: ['mark'], buffered: true });
500
501for (let n = 0; n < 3; n++)
502  performance.mark(`test${n}`);
503```
504
505## Class: `PerformanceObserverEntryList`
506<!-- YAML
507added: v8.5.0
508-->
509
510The `PerformanceObserverEntryList` class is used to provide access to the
511`PerformanceEntry` instances passed to a `PerformanceObserver`.
512The constructor of this class is not exposed to users.
513
514### `performanceObserverEntryList.getEntries()`
515<!-- YAML
516added: v8.5.0
517-->
518
519* Returns: {PerformanceEntry[]}
520
521Returns a list of `PerformanceEntry` objects in chronological order
522with respect to `performanceEntry.startTime`.
523
524```js
525const {
526  performance,
527  PerformanceObserver
528} = require('perf_hooks');
529
530const obs = new PerformanceObserver((perfObserverList, observer) => {
531  console.log(perfObserverList.getEntries());
532  /**
533   * [
534   *   PerformanceEntry {
535   *     name: 'test',
536   *     entryType: 'mark',
537   *     startTime: 81.465639,
538   *     duration: 0
539   *   },
540   *   PerformanceEntry {
541   *     name: 'meow',
542   *     entryType: 'mark',
543   *     startTime: 81.860064,
544   *     duration: 0
545   *   }
546   * ]
547   */
548  observer.disconnect();
549});
550obs.observe({ entryTypes: ['mark'], buffered: true });
551
552performance.mark('test');
553performance.mark('meow');
554```
555
556### `performanceObserverEntryList.getEntriesByName(name[, type])`
557<!-- YAML
558added: v8.5.0
559-->
560
561* `name` {string}
562* `type` {string}
563* Returns: {PerformanceEntry[]}
564
565Returns a list of `PerformanceEntry` objects in chronological order
566with respect to `performanceEntry.startTime` whose `performanceEntry.name` is
567equal to `name`, and optionally, whose `performanceEntry.entryType` is equal to
568`type`.
569
570```js
571const {
572  performance,
573  PerformanceObserver
574} = require('perf_hooks');
575
576const obs = new PerformanceObserver((perfObserverList, observer) => {
577  console.log(perfObserverList.getEntriesByName('meow'));
578  /**
579   * [
580   *   PerformanceEntry {
581   *     name: 'meow',
582   *     entryType: 'mark',
583   *     startTime: 98.545991,
584   *     duration: 0
585   *   }
586   * ]
587   */
588  console.log(perfObserverList.getEntriesByName('nope')); // []
589
590  console.log(perfObserverList.getEntriesByName('test', 'mark'));
591  /**
592   * [
593   *   PerformanceEntry {
594   *     name: 'test',
595   *     entryType: 'mark',
596   *     startTime: 63.518931,
597   *     duration: 0
598   *   }
599   * ]
600   */
601  console.log(perfObserverList.getEntriesByName('test', 'measure')); // []
602  observer.disconnect();
603});
604obs.observe({ entryTypes: ['mark', 'measure'], buffered: true });
605
606performance.mark('test');
607performance.mark('meow');
608```
609
610### `performanceObserverEntryList.getEntriesByType(type)`
611<!-- YAML
612added: v8.5.0
613-->
614
615* `type` {string}
616* Returns: {PerformanceEntry[]}
617
618Returns a list of `PerformanceEntry` objects in chronological order
619with respect to `performanceEntry.startTime` whose `performanceEntry.entryType`
620is equal to `type`.
621
622```js
623const {
624  performance,
625  PerformanceObserver
626} = require('perf_hooks');
627
628const obs = new PerformanceObserver((perfObserverList, observer) => {
629  console.log(perfObserverList.getEntriesByType('mark'));
630  /**
631   * [
632   *   PerformanceEntry {
633   *     name: 'test',
634   *     entryType: 'mark',
635   *     startTime: 55.897834,
636   *     duration: 0
637   *   },
638   *   PerformanceEntry {
639   *     name: 'meow',
640   *     entryType: 'mark',
641   *     startTime: 56.350146,
642   *     duration: 0
643   *   }
644   * ]
645   */
646  observer.disconnect();
647});
648obs.observe({ entryTypes: ['mark'], buffered: true });
649
650performance.mark('test');
651performance.mark('meow');
652```
653
654## `perf_hooks.createHistogram([options])`
655<!-- YAML
656added: v14.18.0
657-->
658
659* `options` {Object}
660  * `min` {number|bigint} The minimum recordable value. Must be an integer
661    value greater than 0. **Defaults**: `1`.
662  * `max` {number|bigint} The maximum recordable value. Must be an integer
663    value greater than `min`. **Defaults**: `Number.MAX_SAFE_INTEGER`.
664  * `figures` {number} The number of accuracy digits. Must be a number between
665    `1` and `5`. **Defaults**: `3`.
666* Returns {RecordableHistogram}
667
668Returns a {RecordableHistogram}.
669
670## `perf_hooks.monitorEventLoopDelay([options])`
671<!-- YAML
672added: v11.10.0
673-->
674
675* `options` {Object}
676  * `resolution` {number} The sampling rate in milliseconds. Must be greater
677    than zero. **Default:** `10`.
678* Returns: {IntervalHistogram}
679
680_This property is an extension by Node.js. It is not available in Web browsers._
681
682Creates an `IntervalHistogram` object that samples and reports the event loop
683delay over time. The delays will be reported in nanoseconds.
684
685Using a timer to detect approximate event loop delay works because the
686execution of timers is tied specifically to the lifecycle of the libuv
687event loop. That is, a delay in the loop will cause a delay in the execution
688of the timer, and those delays are specifically what this API is intended to
689detect.
690
691```js
692const { monitorEventLoopDelay } = require('perf_hooks');
693const h = monitorEventLoopDelay({ resolution: 20 });
694h.enable();
695// Do something.
696h.disable();
697console.log(h.min);
698console.log(h.max);
699console.log(h.mean);
700console.log(h.stddev);
701console.log(h.percentiles);
702console.log(h.percentile(50));
703console.log(h.percentile(99));
704```
705
706## Class: `Histogram`
707<!-- YAML
708added: v11.10.0
709-->
710
711### `histogram.exceeds`
712<!-- YAML
713added: v11.10.0
714-->
715
716* {number}
717
718The number of times the event loop delay exceeded the maximum 1 hour event
719loop delay threshold.
720
721### `histogram.max`
722<!-- YAML
723added: v11.10.0
724-->
725
726* {number}
727
728The maximum recorded event loop delay.
729
730### `histogram.mean`
731<!-- YAML
732added: v11.10.0
733-->
734
735* {number}
736
737The mean of the recorded event loop delays.
738
739### `histogram.min`
740<!-- YAML
741added: v11.10.0
742-->
743
744* {number}
745
746The minimum recorded event loop delay.
747
748### `histogram.percentile(percentile)`
749<!-- YAML
750added: v11.10.0
751-->
752
753* `percentile` {number} A percentile value in the range (0, 100].
754* Returns: {number}
755
756Returns the value at the given percentile.
757
758### `histogram.percentiles`
759<!-- YAML
760added: v11.10.0
761-->
762
763* {Map}
764
765Returns a `Map` object detailing the accumulated percentile distribution.
766
767### `histogram.reset()`
768<!-- YAML
769added: v11.10.0
770-->
771
772Resets the collected histogram data.
773
774### `histogram.stddev`
775<!-- YAML
776added: v11.10.0
777-->
778
779* {number}
780
781The standard deviation of the recorded event loop delays.
782
783## Class: `IntervalHistogram extends Histogram`
784
785A `Histogram` that is periodically updated on a given interval.
786
787### `histogram.disable()`
788<!-- YAML
789added: v11.10.0
790-->
791
792* Returns: {boolean}
793
794Disables the update interval timer. Returns `true` if the timer was
795stopped, `false` if it was already stopped.
796
797### `histogram.enable()`
798<!-- YAML
799added: v11.10.0
800-->
801
802* Returns: {boolean}
803
804Enables the update interval timer. Returns `true` if the timer was
805started, `false` if it was already started.
806
807### Cloning an `IntervalHistogram`
808
809{IntervalHistogram} instances can be cloned via {MessagePort}. On the receiving
810end, the histogram is cloned as a plain {Histogram} object that does not
811implement the `enable()` and `disable()` methods.
812
813## Class: `RecordableHistogram extends Histogram`
814<!-- YAML
815added: v14.18.0
816-->
817
818### `histogram.record(val)`
819<!-- YAML
820added: v14.18.0
821-->
822
823* `val` {number|bigint} The amount to record in the histogram.
824
825### `histogram.recordDelta()`
826<!-- YAML
827added: v14.18.0
828-->
829
830Calculates the amount of time (in nanoseconds) that has passed since the
831previous call to `recordDelta()` and records that amount in the histogram.
832
833## Examples
834
835### Measuring the duration of async operations
836
837The following example uses the [Async Hooks][] and Performance APIs to measure
838the actual duration of a Timeout operation (including the amount of time it took
839to execute the callback).
840
841```js
842'use strict';
843const async_hooks = require('async_hooks');
844const {
845  performance,
846  PerformanceObserver
847} = require('perf_hooks');
848
849const set = new Set();
850const hook = async_hooks.createHook({
851  init(id, type) {
852    if (type === 'Timeout') {
853      performance.mark(`Timeout-${id}-Init`);
854      set.add(id);
855    }
856  },
857  destroy(id) {
858    if (set.has(id)) {
859      set.delete(id);
860      performance.mark(`Timeout-${id}-Destroy`);
861      performance.measure(`Timeout-${id}`,
862                          `Timeout-${id}-Init`,
863                          `Timeout-${id}-Destroy`);
864    }
865  }
866});
867hook.enable();
868
869const obs = new PerformanceObserver((list, observer) => {
870  console.log(list.getEntries()[0]);
871  performance.clearMarks();
872  observer.disconnect();
873});
874obs.observe({ entryTypes: ['measure'], buffered: true });
875
876setTimeout(() => {}, 1000);
877```
878
879### Measuring how long it takes to load dependencies
880
881The following example measures the duration of `require()` operations to load
882dependencies:
883
884<!-- eslint-disable no-global-assign -->
885```js
886'use strict';
887const {
888  performance,
889  PerformanceObserver
890} = require('perf_hooks');
891const mod = require('module');
892
893// Monkey patch the require function
894mod.Module.prototype.require =
895  performance.timerify(mod.Module.prototype.require);
896require = performance.timerify(require);
897
898// Activate the observer
899const obs = new PerformanceObserver((list) => {
900  const entries = list.getEntries();
901  entries.forEach((entry) => {
902    console.log(`require('${entry[0]}')`, entry.duration);
903  });
904  obs.disconnect();
905});
906obs.observe({ entryTypes: ['function'], buffered: true });
907
908require('some-module');
909```
910
911[Async Hooks]: async_hooks.md
912[High Resolution Time]: https://www.w3.org/TR/hr-time-2
913[Performance Timeline]: https://w3c.github.io/performance-timeline/
914[User Timing]: https://www.w3.org/TR/user-timing/
915[Web Performance APIs]: https://w3c.github.io/perf-timing-primer/
916[Worker threads]: worker_threads.md#worker_threads_worker_threads
917[`'exit'`]: process.md#process_event_exit
918[`child_process.spawnSync()`]: child_process.md#child_process_child_process_spawnsync_command_args_options
919[`process.hrtime()`]: process.md#process_process_hrtime_time
920[`timeOrigin`]: https://w3c.github.io/hr-time/#dom-performance-timeorigin
921[`window.performance`]: https://developer.mozilla.org/en-US/docs/Web/API/Window/performance
922