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