Skip to content

Commit d2d0f6f

Browse files
RafaelGSSjuanarbol
authored andcommitted
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 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>
1 parent 084a760 commit d2d0f6f

File tree

8 files changed

+781
-3
lines changed

8 files changed

+781
-3
lines changed
+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
'use strict';
2+
3+
const common = require('../common.js');
4+
5+
const {
6+
PerformanceObserver,
7+
performance,
8+
} = require('perf_hooks');
9+
10+
function createTimingInfo({
11+
startTime = 0,
12+
redirectStartTime = 0,
13+
redirectEndTime = 0,
14+
postRedirectStartTime = 0,
15+
finalServiceWorkerStartTime = 0,
16+
finalNetworkRequestStartTime = 0,
17+
finalNetworkResponseStartTime = 0,
18+
endTime = 0,
19+
encodedBodySize = 0,
20+
decodedBodySize = 0,
21+
finalConnectionTimingInfo = null
22+
}) {
23+
if (finalConnectionTimingInfo !== null) {
24+
finalConnectionTimingInfo.domainLookupStartTime =
25+
finalConnectionTimingInfo.domainLookupStartTime || 0;
26+
finalConnectionTimingInfo.domainLookupEndTime =
27+
finalConnectionTimingInfo.domainLookupEndTime || 0;
28+
finalConnectionTimingInfo.connectionStartTime =
29+
finalConnectionTimingInfo.connectionStartTime || 0;
30+
finalConnectionTimingInfo.connectionEndTime =
31+
finalConnectionTimingInfo.connectionEndTime || 0;
32+
finalConnectionTimingInfo.secureConnectionStartTime =
33+
finalConnectionTimingInfo.secureConnectionStartTime || 0;
34+
finalConnectionTimingInfo.ALPNNegotiatedProtocol =
35+
finalConnectionTimingInfo.ALPNNegotiatedProtocol || [];
36+
}
37+
return {
38+
startTime,
39+
redirectStartTime,
40+
redirectEndTime,
41+
postRedirectStartTime,
42+
finalServiceWorkerStartTime,
43+
finalNetworkRequestStartTime,
44+
finalNetworkResponseStartTime,
45+
endTime,
46+
encodedBodySize,
47+
decodedBodySize,
48+
finalConnectionTimingInfo,
49+
};
50+
}
51+
52+
const bench = common.createBenchmark(main, {
53+
n: [1e5],
54+
observe: ['resource'],
55+
});
56+
57+
function test() {
58+
const timingInfo = createTimingInfo({ finalConnectionTimingInfo: {} });
59+
performance.markResourceTiming(
60+
timingInfo,
61+
'http://localhost:8080',
62+
'fetch',
63+
{},
64+
''
65+
);
66+
}
67+
68+
function main({ n, observe }) {
69+
const obs = new PerformanceObserver(() => {
70+
bench.end(n);
71+
});
72+
obs.observe({ entryTypes: [observe], buffered: true });
73+
74+
bench.start();
75+
for (let i = 0; i < 1e5; i++)
76+
test();
77+
}

doc/api/perf_hooks.md

+223
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Node.js supports the following [Web Performance APIs][]:
1515
* [High Resolution Time][]
1616
* [Performance Timeline][]
1717
* [User Timing][]
18+
* [Resource Timing][]
1819

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

70+
### `performance.clearResourceTimings([name])`
71+
72+
<!-- YAML
73+
added: REPLACEME
74+
-->
75+
76+
* `name` {string}
77+
78+
If `name` is not provided, removes all `PerformanceResourceTiming` objects from
79+
the Resource Timeline. If `name` is provided, removes only the named resource.
80+
6981
### `performance.eventLoopUtilization([utilization1[, utilization2]])`
7082

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

213+
### \`performance.markResourceTiming(timingInfo, requestedUrl, initiatorType,
214+
215+
global, cacheMode)\`
216+
217+
<!-- YAML
218+
added: REPLACEME
219+
-->
220+
221+
* `timingInfo` {Object} [Fetch Timing Info][]
222+
* `requestedUrl` {string} The resource url
223+
* `initiatorType` {string} The initiator name, e.g: 'fetch'
224+
* `global` {Object}
225+
* `cacheMode` {string} The cache mode must be an empty string ('') or 'local'
226+
227+
_This property is an extension by Node.js. It is not available in Web browsers._
228+
229+
Creates a new `PerformanceResourceTiming` entry in the Resource Timeline. A
230+
`PerformanceResourceTiming` is a subclass of `PerformanceEntry` whose
231+
`performanceEntry.entryType` is always `'resource'`. Performance resources
232+
are used to mark moments in the Resource Timeline.
233+
234+
The created `PerformanceMark` entry is put in the global Resource Timeline
235+
and can be queried with `performance.getEntries`,
236+
`performance.getEntriesByName`, and `performance.getEntriesByType`. When the
237+
observation is performed, the entries should be cleared from the global
238+
Performance Timeline manually with `performance.clearResourceTimings`.
239+
201240
### `performance.measure(name[, startMarkOrOptions[, endMark]])`
202241

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

695+
## Class: `PerformanceResourceTiming`
696+
697+
<!-- YAML
698+
added: REPLACEME
699+
-->
700+
701+
* Extends: {PerformanceEntry}
702+
703+
Provides detailed network timing data regarding the loading of an application's
704+
resources.
705+
706+
The constructor of this class is not exposed to users directly.
707+
708+
### `performanceResourceTiming.workerStart`
709+
710+
<!-- YAML
711+
added: REPLACEME
712+
-->
713+
714+
* {number}
715+
716+
The high resolution millisecond timestamp at immediately before dispatching
717+
the `fetch` request. If the resource is not intercepted by a worker the property
718+
will always return 0.
719+
720+
### `performanceResourceTiming.redirectStart`
721+
722+
<!-- YAML
723+
added: REPLACEME
724+
-->
725+
726+
* {number}
727+
728+
The high resolution millisecond timestamp that represents the start time
729+
of the fetch which initiates the redirect.
730+
731+
### `performanceResourceTiming.redirectEnd`
732+
733+
<!-- YAML
734+
added: REPLACEME
735+
-->
736+
737+
* {number}
738+
739+
The high resolution millisecond timestamp that will be created immediately after
740+
receiving the last byte of the response of the last redirect.
741+
742+
### `performanceResourceTiming.fetchStart`
743+
744+
<!-- YAML
745+
added: REPLACEME
746+
-->
747+
748+
* {number}
749+
750+
The high resolution millisecond timestamp immediately before the Node.js starts
751+
to fetch the resource.
752+
753+
### `performanceResourceTiming.domainLookupStart`
754+
755+
<!-- YAML
756+
added: REPLACEME
757+
-->
758+
759+
* {number}
760+
761+
The high resolution millisecond timestamp immediately before the Node.js starts
762+
the domain name lookup for the resource.
763+
764+
### `performanceResourceTiming.domainLookupEnd`
765+
766+
<!-- YAML
767+
added: REPLACEME
768+
-->
769+
770+
* {number}
771+
772+
The high resolution millisecond timestamp representing the time immediately
773+
after the Node.js finished the domain name lookup for the resource.
774+
775+
### `performanceResourceTiming.connectStart`
776+
777+
<!-- YAML
778+
added: REPLACEME
779+
-->
780+
781+
* {number}
782+
783+
The high resolution millisecond timestamp representing the time immediately
784+
before Node.js starts to establish the connection to the server to retrieve
785+
the resource.
786+
787+
### `performanceResourceTiming.connectEnd`
788+
789+
<!-- YAML
790+
added: REPLACEME
791+
-->
792+
793+
* {number}
794+
795+
The high resolution millisecond timestamp representing the time immediately
796+
after Node.js finishes establishing the connection to the server to retrieve
797+
the resource.
798+
799+
### `performanceResourceTiming.secureConnectionStart`
800+
801+
<!-- YAML
802+
added: REPLACEME
803+
-->
804+
805+
* {number}
806+
807+
The high resolution millisecond timestamp representing the time immediately
808+
before Node.js starts the handshake process to secure the current connection.
809+
810+
### `performanceResourceTiming.requestStart`
811+
812+
<!-- YAML
813+
added: REPLACEME
814+
-->
815+
816+
* {number}
817+
818+
The high resolution millisecond timestamp representing the time immediately
819+
before Node.js receives the first byte of the response from the server.
820+
821+
### `performanceResourceTiming.responseEnd`
822+
823+
<!-- YAML
824+
added: REPLACEME
825+
-->
826+
827+
* {number}
828+
829+
The high resolution millisecond timestamp representing the time immediately
830+
after Node.js receives the last byte of the resource or immediately before
831+
the transport connection is closed, whichever comes first.
832+
833+
### `performanceResourceTiming.transferSize`
834+
835+
<!-- YAML
836+
added: REPLACEME
837+
-->
838+
839+
* {number}
840+
841+
A number representing the size (in octets) of the fetched resource. The size
842+
includes the response header fields plus the response payload body.
843+
844+
### `performanceResourceTiming.encodedBodySize`
845+
846+
<!-- YAML
847+
added: REPLACEME
848+
-->
849+
850+
* {number}
851+
852+
A number representing the size (in octets) received from the fetch
853+
(HTTP or cache), of the payload body, before removing any applied
854+
content-codings.
855+
856+
### `performanceResourceTiming.decodedBodySize`
857+
858+
<!-- YAML
859+
added: REPLACEME
860+
-->
861+
862+
* {number}
863+
864+
A number representing the size (in octets) received from the fetch
865+
(HTTP or cache), of the message body, after removing any applied
866+
content-codings.
867+
868+
### `performanceResourceTiming.toJSON()`
869+
870+
<!-- YAML
871+
added: REPLACEME
872+
-->
873+
874+
Returns a `object` that is the JSON representation of the
875+
`PerformanceResourceTiming` object
876+
656877
## Class: `perf_hooks.PerformanceObserver`
657878

658879
### `new PerformanceObserver(callback)`
@@ -1337,8 +1558,10 @@ dns.promises.resolve('localhost');
13371558
```
13381559

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

0 commit comments

Comments
 (0)