You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

611 lines
23 KiB

/**
* 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
* Node.js-specific performance measurements.
*
* Node.js supports the following [Web Performance APIs](https://w3c.github.io/perf-timing-primer/):
*
* * [High Resolution Time](https://www.w3.org/TR/hr-time-2)
* * [Performance Timeline](https://w3c.github.io/performance-timeline/)
* * [User Timing](https://www.w3.org/TR/user-timing/)
*
* ```js
* const { PerformanceObserver, performance } = require('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');
* });
* ```
* @see [source](https://github.com/nodejs/node/blob/v18.0.0/lib/perf_hooks.js)
*/
declare module 'perf_hooks' {
import { AsyncResource } from 'node:async_hooks';
type EntryType = 'node' | 'mark' | 'measure' | 'gc' | 'function' | 'http2' | 'http';
interface NodeGCPerformanceDetail {
/**
* When `performanceEntry.entryType` is equal to 'gc', `the performance.kind` property identifies
* the type of garbage collection operation that occurred.
* See perf_hooks.constants for valid values.
*/
readonly kind?: number | undefined;
/**
* When `performanceEntry.entryType` is equal to 'gc', the `performance.flags`
* property contains additional information about garbage collection operation.
* See perf_hooks.constants for valid values.
*/
readonly flags?: number | undefined;
}
/**
* @since v8.5.0
*/
class PerformanceEntry {
protected constructor();
/**
* The total number of milliseconds elapsed for this entry. This value will not
* be meaningful for all Performance Entry types.
* @since v8.5.0
*/
readonly duration: number;
/**
* The name of the performance entry.
* @since v8.5.0
*/
readonly name: string;
/**
* The high resolution millisecond timestamp marking the starting time of the
* Performance Entry.
* @since v8.5.0
*/
readonly startTime: number;
/**
* The type of the performance entry. It may be one of:
*
* * `'node'` (Node.js only)
* * `'mark'` (available on the Web)
* * `'measure'` (available on the Web)
* * `'gc'` (Node.js only)
* * `'function'` (Node.js only)
* * `'http2'` (Node.js only)
* * `'http'` (Node.js only)
* @since v8.5.0
*/
readonly entryType: EntryType;
/**
* Additional detail specific to the `entryType`.
* @since v16.0.0
*/
readonly detail?: NodeGCPerformanceDetail | unknown | undefined; // TODO: Narrow this based on entry type.
toJSON(): any;
}
class PerformanceMark extends PerformanceEntry {
readonly duration: 0;
readonly entryType: 'mark';
}
class PerformanceMeasure extends PerformanceEntry {
readonly entryType: 'measure';
}
/**
* _This property is an extension by Node.js. It is not available in Web browsers._
*
* Provides timing details for Node.js itself. The constructor of this class
* is not exposed to users.
* @since v8.5.0
*/
class PerformanceNodeTiming extends PerformanceEntry {
/**
* The high resolution millisecond timestamp at which the Node.js process
* completed bootstrapping. If bootstrapping has not yet finished, the property
* has the value of -1.
* @since v8.5.0
*/
readonly bootstrapComplete: number;
/**
* The high resolution millisecond timestamp at which the Node.js environment was
* initialized.
* @since v8.5.0
*/
readonly environment: number;
/**
* The high resolution millisecond timestamp of the amount of time the event loop
* has been idle within the event loop's event provider (e.g. `epoll_wait`). This
* does not take CPU usage into consideration. If the event loop has not yet
* started (e.g., in the first tick of the main script), the property has the
* value of 0.
* @since v14.10.0, v12.19.0
*/
readonly idleTime: number;
/**
* The high resolution millisecond timestamp at which the Node.js event loop
* exited. If the event loop has not yet exited, the property has the value of -1\.
* It can only have a value of not -1 in a handler of the `'exit'` event.
* @since v8.5.0
*/
readonly loopExit: number;
/**
* The high resolution millisecond timestamp at which the Node.js event loop
* started. If the event loop has not yet started (e.g., in the first tick of the
* main script), the property has the value of -1.
* @since v8.5.0
*/
readonly loopStart: number;
/**
* The high resolution millisecond timestamp at which the V8 platform was
* initialized.
* @since v8.5.0
*/
readonly v8Start: number;
}
interface EventLoopUtilization {
idle: number;
active: number;
utilization: number;
}
/**
* @param util1 The result of a previous call to eventLoopUtilization()
* @param util2 The result of a previous call to eventLoopUtilization() prior to util1
*/
type EventLoopUtilityFunction = (util1?: EventLoopUtilization, util2?: EventLoopUtilization) => EventLoopUtilization;
interface MarkOptions {
/**
* Additional optional detail to include with the mark.
*/
detail?: unknown | undefined;
/**
* An optional timestamp to be used as the mark time.
* @default `performance.now()`.
*/
startTime?: number | undefined;
}
interface MeasureOptions {
/**
* Additional optional detail to include with the mark.
*/
detail?: unknown | undefined;
/**
* Duration between start and end times.
*/
duration?: number | undefined;
/**
* Timestamp to be used as the end time, or a string identifying a previously recorded mark.
*/
end?: number | string | undefined;
/**
* Timestamp to be used as the start time, or a string identifying a previously recorded mark.
*/
start?: number | string | undefined;
}
interface TimerifyOptions {
/**
* A histogram object created using
* `perf_hooks.createHistogram()` that will record runtime durations in
* nanoseconds.
*/
histogram?: RecordableHistogram | undefined;
}
interface Performance {
/**
* If name is not provided, removes all PerformanceMark objects from the Performance Timeline.
* If name is provided, removes only the named mark.
* @param name
*/
clearMarks(name?: string): void;
/**
* If name is not provided, removes all PerformanceMeasure objects from the Performance Timeline.
* If name is provided, removes only the named measure.
* @param name
* @since v16.7.0
*/
clearMeasures(name?: string): void;
/**
* Returns a list of `PerformanceEntry` objects in chronological order with respect to `performanceEntry.startTime`.
* If you are only interested in performance entries of certain types or that have certain names, see
* `performance.getEntriesByType()` and `performance.getEntriesByName()`.
* @since v16.7.0
*/
getEntries(): PerformanceEntry[];
/**
* Returns a list of `PerformanceEntry` objects in chronological order with respect to `performanceEntry.startTime`
* whose `performanceEntry.name` is equal to `name`, and optionally, whose `performanceEntry.entryType` is equal to `type`.
* @param name
* @param type
* @since v16.7.0
*/
getEntriesByName(name: string, type?: EntryType): PerformanceEntry[];
/**
* Returns a list of `PerformanceEntry` objects in chronological order with respect to `performanceEntry.startTime`
* whose `performanceEntry.entryType` is equal to `type`.
* @param type
* @since v16.7.0
*/
getEntriesByType(type: EntryType): PerformanceEntry[];
/**
* Creates a new PerformanceMark entry in the Performance Timeline.
* A PerformanceMark is a subclass of PerformanceEntry whose performanceEntry.entryType is always 'mark',
* and whose performanceEntry.duration is always 0.
* Performance marks are used to mark specific significant moments in the Performance Timeline.
* @param name
* @return The PerformanceMark entry that was created
*/
mark(name?: string, options?: MarkOptions): PerformanceMark;
/**
* Creates a new PerformanceMeasure entry in the Performance Timeline.
* A PerformanceMeasure is a subclass of PerformanceEntry whose performanceEntry.entryType is always 'measure',
* and whose performanceEntry.duration measures the number of milliseconds elapsed since startMark and endMark.
*
* The startMark argument may identify any existing PerformanceMark in the the Performance Timeline, or may identify
* any of the timestamp properties provided by the PerformanceNodeTiming class. If the named startMark does not exist,
* then startMark is set to timeOrigin by default.
*
* The endMark argument must identify any existing PerformanceMark in the the Performance Timeline or any of the timestamp
* properties provided by the PerformanceNodeTiming class. If the named endMark does not exist, an error will be thrown.
* @param name
* @param startMark
* @param endMark
* @return The PerformanceMeasure entry that was created
*/
measure(name: string, startMark?: string, endMark?: string): PerformanceMeasure;
measure(name: string, options: MeasureOptions): PerformanceMeasure;
/**
* An instance of the PerformanceNodeTiming class that provides performance metrics for specific Node.js operational milestones.
*/
readonly nodeTiming: PerformanceNodeTiming;
/**
* @return the current high resolution millisecond timestamp
*/
now(): number;
/**
* The timeOrigin specifies the high resolution millisecond timestamp from which all performance metric durations are measured.
*/
readonly timeOrigin: number;
/**
* Wraps a function within a new function that measures the running time of the wrapped function.
* A PerformanceObserver must be subscribed to the 'function' event type in order for the timing details to be accessed.
* @param fn
*/
timerify<T extends (...params: any[]) => any>(fn: T, options?: TimerifyOptions): T;
/**
* eventLoopUtilization is similar to CPU utilization except that it is calculated using high precision wall-clock time.
* It represents the percentage of time the event loop has spent outside the event loop's event provider (e.g. epoll_wait).
* No other CPU idle time is taken into consideration.
*/
eventLoopUtilization: EventLoopUtilityFunction;
}
interface PerformanceObserverEntryList {
/**
* Returns a list of `PerformanceEntry` objects in chronological order
* with respect to `performanceEntry.startTime`.
*
* ```js
* const {
* performance,
* PerformanceObserver
* } = require('perf_hooks');
*
* const obs = new PerformanceObserver((perfObserverList, observer) => {
* console.log(perfObserverList.getEntries());
*
* * [
* * PerformanceEntry {
* * name: 'test',
* * entryType: 'mark',
* * startTime: 81.465639,
* * duration: 0
* * },
* * PerformanceEntry {
* * name: 'meow',
* * entryType: 'mark',
* * startTime: 81.860064,
* * duration: 0
* * }
* * ]
*
*
* performance.clearMarks();
* performance.clearMeasures();
* observer.disconnect();
* });
* obs.observe({ type: 'mark' });
*
* performance.mark('test');
* performance.mark('meow');
* ```
* @since v8.5.0
*/
getEntries(): PerformanceEntry[];
/**
* Returns a list of `PerformanceEntry` objects in chronological order
* with respect to `performanceEntry.startTime` whose `performanceEntry.name` is
* equal to `name`, and optionally, whose `performanceEntry.entryType` is equal to`type`.
*
* ```js
* const {
* performance,
* PerformanceObserver
* } = require('perf_hooks');
*
* const obs = new PerformanceObserver((perfObserverList, observer) => {
* console.log(perfObserverList.getEntriesByName('meow'));
*
* * [
* * PerformanceEntry {
* * name: 'meow',
* * entryType: 'mark',
* * startTime: 98.545991,
* * duration: 0
* * }
* * ]
*
* console.log(perfObserverList.getEntriesByName('nope')); // []
*
* console.log(perfObserverList.getEntriesByName('test', 'mark'));
*
* * [
* * PerformanceEntry {
* * name: 'test',
* * entryType: 'mark',
* * startTime: 63.518931,
* * duration: 0
* * }
* * ]
*
* console.log(perfObserverList.getEntriesByName('test', 'measure')); // []
*
* performance.clearMarks();
* performance.clearMeasures();
* observer.disconnect();
* });
* obs.observe({ entryTypes: ['mark', 'measure'] });
*
* performance.mark('test');
* performance.mark('meow');
* ```
* @since v8.5.0
*/
getEntriesByName(name: string, type?: EntryType): PerformanceEntry[];
/**
* Returns a list of `PerformanceEntry` objects in chronological order
* with respect to `performanceEntry.startTime` whose `performanceEntry.entryType`is equal to `type`.
*
* ```js
* const {
* performance,
* PerformanceObserver
* } = require('perf_hooks');
*
* const obs = new PerformanceObserver((perfObserverList, observer) => {
* console.log(perfObserverList.getEntriesByType('mark'));
*
* * [
* * PerformanceEntry {
* * name: 'test',
* * entryType: 'mark',
* * startTime: 55.897834,
* * duration: 0
* * },
* * PerformanceEntry {
* * name: 'meow',
* * entryType: 'mark',
* * startTime: 56.350146,
* * duration: 0
* * }
* * ]
*
* performance.clearMarks();
* performance.clearMeasures();
* observer.disconnect();
* });
* obs.observe({ type: 'mark' });
*
* performance.mark('test');
* performance.mark('meow');
* ```
* @since v8.5.0
*/
getEntriesByType(type: EntryType): PerformanceEntry[];
}
type PerformanceObserverCallback = (list: PerformanceObserverEntryList, observer: PerformanceObserver) => void;
class PerformanceObserver extends AsyncResource {
constructor(callback: PerformanceObserverCallback);
/**
* Disconnects the `PerformanceObserver` instance from all notifications.
* @since v8.5.0
*/
disconnect(): void;
/**
* Subscribes the `PerformanceObserver` instance to notifications of new `PerformanceEntry` instances identified either by `options.entryTypes`or `options.type`:
*
* ```js
* const {
* performance,
* PerformanceObserver
* } = require('perf_hooks');
*
* const obs = new PerformanceObserver((list, observer) => {
* // Called once asynchronously. `list` contains three items.
* });
* obs.observe({ type: 'mark' });
*
* for (let n = 0; n < 3; n++)
* performance.mark(`test${n}`);
* ```
* @since v8.5.0
*/
observe(
options:
| {
entryTypes: ReadonlyArray<EntryType>;
buffered?: boolean | undefined;
}
| {
type: EntryType;
buffered?: boolean | undefined;
}
): void;
}
namespace constants {
const NODE_PERFORMANCE_GC_MAJOR: number;
const NODE_PERFORMANCE_GC_MINOR: number;
const NODE_PERFORMANCE_GC_INCREMENTAL: number;
const NODE_PERFORMANCE_GC_WEAKCB: number;
const NODE_PERFORMANCE_GC_FLAGS_NO: number;
const NODE_PERFORMANCE_GC_FLAGS_CONSTRUCT_RETAINED: number;
const NODE_PERFORMANCE_GC_FLAGS_FORCED: number;
const NODE_PERFORMANCE_GC_FLAGS_SYNCHRONOUS_PHANTOM_PROCESSING: number;
const NODE_PERFORMANCE_GC_FLAGS_ALL_AVAILABLE_GARBAGE: number;
const NODE_PERFORMANCE_GC_FLAGS_ALL_EXTERNAL_MEMORY: number;
const NODE_PERFORMANCE_GC_FLAGS_SCHEDULE_IDLE: number;
}
const performance: Performance;
interface EventLoopMonitorOptions {
/**
* The sampling rate in milliseconds.
* Must be greater than zero.
* @default 10
*/
resolution?: number | undefined;
}
interface Histogram {
/**
* Returns a `Map` object detailing the accumulated percentile distribution.
* @since v11.10.0
*/
readonly percentiles: Map<number, number>;
/**
* The number of times the event loop delay exceeded the maximum 1 hour event
* loop delay threshold.
* @since v11.10.0
*/
readonly exceeds: number;
/**
* The minimum recorded event loop delay.
* @since v11.10.0
*/
readonly min: number;
/**
* The maximum recorded event loop delay.
* @since v11.10.0
*/
readonly max: number;
/**
* The mean of the recorded event loop delays.
* @since v11.10.0
*/
readonly mean: number;
/**
* The standard deviation of the recorded event loop delays.
* @since v11.10.0
*/
readonly stddev: number;
/**
* Resets the collected histogram data.
* @since v11.10.0
*/
reset(): void;
/**
* Returns the value at the given percentile.
* @since v11.10.0
* @param percentile A percentile value in the range (0, 100].
*/
percentile(percentile: number): number;
}
interface IntervalHistogram extends Histogram {
/**
* Enables the update interval timer. Returns `true` if the timer was
* started, `false` if it was already started.
* @since v11.10.0
*/
enable(): boolean;
/**
* Disables the update interval timer. Returns `true` if the timer was
* stopped, `false` if it was already stopped.
* @since v11.10.0
*/
disable(): boolean;
}
interface RecordableHistogram extends Histogram {
/**
* @since v15.9.0, v14.18.0
* @param val The amount to record in the histogram.
*/
record(val: number | bigint): void;
/**
* Calculates the amount of time (in nanoseconds) that has passed since the
* previous call to `recordDelta()` and records that amount in the histogram.
*
* ## Examples
* @since v15.9.0, v14.18.0
*/
recordDelta(): void;
/**
* Adds the values from other to this histogram.
* @since v17.4.0, v16.14.0
* @param other Recordable Histogram to combine with
*/
add(other: RecordableHistogram): void;
}
/**
* _This property is an extension by Node.js. It is not available in Web browsers._
*
* Creates an `IntervalHistogram` object that samples and reports the event loop
* delay over time. The delays will be reported in nanoseconds.
*
* Using a timer to detect approximate event loop delay works because the
* execution of timers is tied specifically to the lifecycle of the libuv
* event loop. That is, a delay in the loop will cause a delay in the execution
* of the timer, and those delays are specifically what this API is intended to
* detect.
*
* ```js
* const { monitorEventLoopDelay } = require('perf_hooks');
* const h = monitorEventLoopDelay({ resolution: 20 });
* h.enable();
* // Do something.
* 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));
* ```
* @since v11.10.0
*/
function monitorEventLoopDelay(options?: EventLoopMonitorOptions): IntervalHistogram;
interface CreateHistogramOptions {
/**
* The minimum recordable value. Must be an integer value greater than 0.
* @default 1
*/
min?: number | bigint | undefined;
/**
* The maximum recordable value. Must be an integer value greater than min.
* @default Number.MAX_SAFE_INTEGER
*/
max?: number | bigint | undefined;
/**
* The number of accuracy digits. Must be a number between 1 and 5.
* @default 3
*/
figures?: number | undefined;
}
/**
* Returns a `RecordableHistogram`.
* @since v15.9.0, v14.18.0
*/
function createHistogram(options?: CreateHistogramOptions): RecordableHistogram;
}
declare module 'node:perf_hooks' {
export * from 'perf_hooks';
}