-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(fetch): expose timings #32647
feat(fetch): expose timings #32647
Conversation
This comment has been minimized.
This comment has been minimized.
3de1612
to
a7ea946
Compare
This comment has been minimized.
This comment has been minimized.
9c743d9
to
0eb69c3
Compare
This comment has been minimized.
This comment has been minimized.
make responseEnd optional make it more similar to existing types missed one!
0eb69c3
to
8de8383
Compare
@@ -314,7 +314,7 @@ Returns resource size information for given request. | |||
- `startTime` <[float]> Request start time in milliseconds elapsed since January 1, 1970 00:00:00 UTC | |||
- `domainLookupStart` <[float]> Time immediately before the browser starts the domain name lookup for the | |||
resource. The value is given in milliseconds relative to `startTime`, -1 if not available. | |||
- `domainLookupEnd` <[float]> Time immediately after the browser starts the domain name lookup for the resource. | |||
- `domainLookupEnd` <[float]> Time immediately after the browser ends the domain name lookup for the resource. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a drive-by fix - pretty sure it shouldn't say "start the domain name lookup"
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
@@ -483,6 +504,9 @@ export abstract class APIRequestContext extends SdkObject { | |||
socket.on('lookup', () => { dnsLookupAt = monotonicTime(); }); | |||
socket.on('connect', () => { tcpConnectionAt = monotonicTime(); }); | |||
socket.on('secureConnect', () => { tlsHandshakeAt = monotonicTime(); }); | |||
|
|||
// socks / http proxy | |||
socket.on('proxyConnect', () => { tcpConnectionAt = monotonicTime(); }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding timings to the protocol uncovered that tcpConnectionAt
was undefined for requests over SOCKS and HTTPS Proxy. Turns out that the library we use for that doesn't emit the connect
event, but the proxyConnect
event instead.
This comment has been minimized.
This comment has been minimized.
const endAt = monotonicTime(); | ||
// spec: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming | ||
const timing: channels.ResourceTiming = { | ||
startTime: startAt, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docs say startTime
is a wall time, not monotonic time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done in b717257
// spec: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming | ||
const timing: channels.ResourceTiming = { | ||
startTime: startAt, | ||
domainLookupStart: dnsLookupAt ? 0 : -1, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why zero and not relativeTime()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understand is that the browser has some other steps like cache resolution before the DNS lookup, so there might be time between startTime and the DNS lookup start. On Node.js, I don't think there's anything between that - so it's zero, because we know the DNS lookup happens immediately after the request start.
const timing: channels.ResourceTiming = { | ||
startTime: startAt, | ||
domainLookupStart: dnsLookupAt ? 0 : -1, | ||
domainLookupEnd: dnsLookupAt ? dnsLookupAt! - startAt : -1, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
relativeTime()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done in b1d523b
body | ||
body, | ||
timing, | ||
responseEndTiming, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we have two sets of timings now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For browser requests, most of the timings are transmitted in the Response
type, and then responseEndTiming
arrives later in the requestFinished
and requestFailed
events. I opted to make this similar, so we have a big set of timings in timing
and the final timing in responseEndTiming
.
I thought about amending the ResourceTiming
type instead, but then requestFinished
would suddenly have the response end time both in responseEndTiming
and in response.timing.responseEnd
- that felt confusing.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Test results for "tests 1"2 failed 3 flaky35496 passed, 659 skipped Merge workflow run. |
We discussed this with the team and decided against exposing this via the API. Playwright isn't a network performance testing tool, and we don't want people using it like one. Rough timings can easily be measured in userland. I'll open a separate PR to fix the bugs around HTTP / SOCKS Proxy we found in the existing measurements for HAR timings. |
) Fixes a bug discovered in #32647. When using http proxy, the `connect` event isn't emitted so we don't populate `tcpConnectionAt`. The updated version of `https-proxy-agent` emits a `proxyConnect` as a replacement, so this PR updates and listens to that event. For socks proxies, the `on("socket")` event is emitted once the SOCKS connection is established, which is the equivalent of having a TCP connection available. --------- Signed-off-by: Simon Knott <[email protected]> Co-authored-by: Max Schmitt <[email protected]>
Closes #19621. Adds the same
timings()
we have for browser responses toAPIResponse
. Please apply some extra care in reviewing the timing calculations.In the protocol change, I was unsure wether to extend the existing
ResourceTiming
type or to add another property. I went with the added property to be in-line with how the events work for browser requests - let me know if we should do it differently instead.