Skip to content

Commit

Permalink
perf_hooks: add PerformanceResourceTiming
Browse files Browse the repository at this point in the history
perf_hooks: create clearResourceTimings

perf_hooks: add resourcetiming test parallel

perf_hooks: add markResourceTiming

perf_hooks: fix observable when using resource

perf_hooks: fix observable when using resource

perf_hooks: add class comments

perf_hooks: add PerformanceResourceTiming

perf_hooks: create clearResourceTimings

perf_hooks: add resourcetiming test parallel

perf_hooks: add markResourceTiming

perf_hooks: fix observable when using resource

perf_hooks: fix observable when using resource

perf_hooks: add class comments

perf_hooks: add Resource Timing documentation

benchmark: measure resource timing module

perf_hooks: add check avoiding new PerformanceResourceTiming

perf_hooks: adjust doc

PR-URL: #42725
Fixes: nodejs/undici#952
Reviewed-By: Robert Nagy <ronagy@icloud.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
  • Loading branch information
RafaelGSS authored and BethGriggs committed May 16, 2022
1 parent 76096c2 commit c92e291
Show file tree
Hide file tree
Showing 8 changed files with 781 additions and 3 deletions.
77 changes: 77 additions & 0 deletions benchmark/perf_hooks/resourcetiming.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
'use strict';

const common = require('../common.js');

const {
PerformanceObserver,
performance,
} = require('perf_hooks');

function createTimingInfo({
startTime = 0,
redirectStartTime = 0,
redirectEndTime = 0,
postRedirectStartTime = 0,
finalServiceWorkerStartTime = 0,
finalNetworkRequestStartTime = 0,
finalNetworkResponseStartTime = 0,
endTime = 0,
encodedBodySize = 0,
decodedBodySize = 0,
finalConnectionTimingInfo = null
}) {
if (finalConnectionTimingInfo !== null) {
finalConnectionTimingInfo.domainLookupStartTime =
finalConnectionTimingInfo.domainLookupStartTime || 0;
finalConnectionTimingInfo.domainLookupEndTime =
finalConnectionTimingInfo.domainLookupEndTime || 0;
finalConnectionTimingInfo.connectionStartTime =
finalConnectionTimingInfo.connectionStartTime || 0;
finalConnectionTimingInfo.connectionEndTime =
finalConnectionTimingInfo.connectionEndTime || 0;
finalConnectionTimingInfo.secureConnectionStartTime =
finalConnectionTimingInfo.secureConnectionStartTime || 0;
finalConnectionTimingInfo.ALPNNegotiatedProtocol =
finalConnectionTimingInfo.ALPNNegotiatedProtocol || [];
}
return {
startTime,
redirectStartTime,
redirectEndTime,
postRedirectStartTime,
finalServiceWorkerStartTime,
finalNetworkRequestStartTime,
finalNetworkResponseStartTime,
endTime,
encodedBodySize,
decodedBodySize,
finalConnectionTimingInfo,
};
}

const bench = common.createBenchmark(main, {
n: [1e5],
observe: ['resource'],
});

function test() {
const timingInfo = createTimingInfo({ finalConnectionTimingInfo: {} });
performance.markResourceTiming(
timingInfo,
'http://localhost:8080',
'fetch',
{},
''
);
}

function main({ n, observe }) {
const obs = new PerformanceObserver(() => {
bench.end(n);
});
obs.observe({ entryTypes: [observe], buffered: true });

bench.start();
for (let i = 0; i < 1e5; i++)
test();
}
223 changes: 223 additions & 0 deletions doc/api/perf_hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Node.js supports the following [Web Performance APIs][]:
* [High Resolution Time][]
* [Performance Timeline][]
* [User Timing][]
* [Resource Timing][]

```js
const { PerformanceObserver, performance } = require('node:perf_hooks');
Expand Down Expand Up @@ -66,6 +67,17 @@ added: v16.7.0
If `name` is not provided, removes all `PerformanceMeasure` objects from the
Performance Timeline. If `name` is provided, removes only the named mark.

### `performance.clearResourceTimings([name])`

<!-- YAML
added: REPLACEME
-->

* `name` {string}

If `name` is not provided, removes all `PerformanceResourceTiming` objects from
the Resource Timeline. If `name` is provided, removes only the named resource.

### `performance.eventLoopUtilization([utilization1[, utilization2]])`

<!-- YAML
Expand Down Expand Up @@ -198,6 +210,33 @@ and can be queried with `performance.getEntries`,
observation is performed, the entries should be cleared from the global
Performance Timeline manually with `performance.clearMarks`.

### \`performance.markResourceTiming(timingInfo, requestedUrl, initiatorType,

global, cacheMode)\`

<!-- YAML
added: REPLACEME
-->

* `timingInfo` {Object} [Fetch Timing Info][]
* `requestedUrl` {string} The resource url
* `initiatorType` {string} The initiator name, e.g: 'fetch'
* `global` {Object}
* `cacheMode` {string} The cache mode must be an empty string ('') or 'local'

_This property is an extension by Node.js. It is not available in Web browsers._

Creates a new `PerformanceResourceTiming` entry in the Resource Timeline. A
`PerformanceResourceTiming` is a subclass of `PerformanceEntry` whose
`performanceEntry.entryType` is always `'resource'`. Performance resources
are used to mark moments in the Resource Timeline.

The created `PerformanceMark` entry is put in the global Resource Timeline
and can be queried with `performance.getEntries`,
`performance.getEntriesByName`, and `performance.getEntriesByType`. When the
observation is performed, the entries should be cleared from the global
Performance Timeline manually with `performance.clearResourceTimings`.

### `performance.measure(name[, startMarkOrOptions[, endMark]])`

<!-- YAML
Expand Down Expand Up @@ -653,6 +692,188 @@ added: v8.5.0
The high resolution millisecond timestamp at which the V8 platform was
initialized.

## Class: `PerformanceResourceTiming`

<!-- YAML
added: REPLACEME
-->

* Extends: {PerformanceEntry}

Provides detailed network timing data regarding the loading of an application's
resources.

The constructor of this class is not exposed to users directly.

### `performanceResourceTiming.workerStart`

<!-- YAML
added: REPLACEME
-->

* {number}

The high resolution millisecond timestamp at immediately before dispatching
the `fetch` request. If the resource is not intercepted by a worker the property
will always return 0.

### `performanceResourceTiming.redirectStart`

<!-- YAML
added: REPLACEME
-->

* {number}

The high resolution millisecond timestamp that represents the start time
of the fetch which initiates the redirect.

### `performanceResourceTiming.redirectEnd`

<!-- YAML
added: REPLACEME
-->

* {number}

The high resolution millisecond timestamp that will be created immediately after
receiving the last byte of the response of the last redirect.

### `performanceResourceTiming.fetchStart`

<!-- YAML
added: REPLACEME
-->

* {number}

The high resolution millisecond timestamp immediately before the Node.js starts
to fetch the resource.

### `performanceResourceTiming.domainLookupStart`

<!-- YAML
added: REPLACEME
-->

* {number}

The high resolution millisecond timestamp immediately before the Node.js starts
the domain name lookup for the resource.

### `performanceResourceTiming.domainLookupEnd`

<!-- YAML
added: REPLACEME
-->

* {number}

The high resolution millisecond timestamp representing the time immediately
after the Node.js finished the domain name lookup for the resource.

### `performanceResourceTiming.connectStart`

<!-- YAML
added: REPLACEME
-->

* {number}

The high resolution millisecond timestamp representing the time immediately
before Node.js starts to establish the connection to the server to retrieve
the resource.

### `performanceResourceTiming.connectEnd`

<!-- YAML
added: REPLACEME
-->

* {number}

The high resolution millisecond timestamp representing the time immediately
after Node.js finishes establishing the connection to the server to retrieve
the resource.

### `performanceResourceTiming.secureConnectionStart`

<!-- YAML
added: REPLACEME
-->

* {number}

The high resolution millisecond timestamp representing the time immediately
before Node.js starts the handshake process to secure the current connection.

### `performanceResourceTiming.requestStart`

<!-- YAML
added: REPLACEME
-->

* {number}

The high resolution millisecond timestamp representing the time immediately
before Node.js receives the first byte of the response from the server.

### `performanceResourceTiming.responseEnd`

<!-- YAML
added: REPLACEME
-->

* {number}

The high resolution millisecond timestamp representing the time immediately
after Node.js receives the last byte of the resource or immediately before
the transport connection is closed, whichever comes first.

### `performanceResourceTiming.transferSize`

<!-- YAML
added: REPLACEME
-->

* {number}

A number representing the size (in octets) of the fetched resource. The size
includes the response header fields plus the response payload body.

### `performanceResourceTiming.encodedBodySize`

<!-- YAML
added: REPLACEME
-->

* {number}

A number representing the size (in octets) received from the fetch
(HTTP or cache), of the payload body, before removing any applied
content-codings.

### `performanceResourceTiming.decodedBodySize`

<!-- YAML
added: REPLACEME
-->

* {number}

A number representing the size (in octets) received from the fetch
(HTTP or cache), of the message body, after removing any applied
content-codings.

### `performanceResourceTiming.toJSON()`

<!-- YAML
added: REPLACEME
-->

Returns a `object` that is the JSON representation of the
`PerformanceResourceTiming` object

## Class: `perf_hooks.PerformanceObserver`

### `new PerformanceObserver(callback)`
Expand Down Expand Up @@ -1367,8 +1588,10 @@ dns.promises.resolve('localhost');
```

[Async Hooks]: async_hooks.md
[Fetch Timing Info]: https://fetch.spec.whatwg.org/#fetch-timing-info
[High Resolution Time]: https://www.w3.org/TR/hr-time-2
[Performance Timeline]: https://w3c.github.io/performance-timeline/
[Resource Timing]: https://www.w3.org/TR/resource-timing-2/
[User Timing]: https://www.w3.org/TR/user-timing/
[Web Performance APIs]: https://w3c.github.io/perf-timing-primer/
[Worker threads]: worker_threads.md#worker-threads
Expand Down
Loading

0 comments on commit c92e291

Please sign in to comment.