w3c / resource-timing

Resource Timing
https://w3c.github.io/resource-timing/
Other
119 stars 35 forks source link

Consider adding finalResponseHeaders{Start|End} times #345

Open noamr opened 1 year ago

noamr commented 1 year ago

Since we've added early hints, now TTFB in RUM, which maps to responseStart means something slightly different than it did before (though technically it represents the same thing).

For services that rely on final response timing, perhaps we should also expose when the final headers started arriving, and when they ended and the body started?

LPardue commented 1 year ago

What is the definition of final that we're using here?

From the HTTP RFC, a server can respond to a single request with multiple interim responses (1xx) and a single final response messages (2xx through 5xx) ; see https://www.rfc-editor.org/rfc/rfc9110.html#section-15.2-3

A client MUST be able to parse one or more 1xx responses received prior to a final response, even if the client does not expect one. A user agent MAY ignore unexpected 1xx responses.

And do we care about measuring the arrival times of trailer field sections on the final response message?

noamr commented 1 year ago

What is the definition of final that we're using here?

From the HTTP RFC, a server can respond to a single request with multiple interim responses (1xx) and a single final response messages (2xx through 5xx) ; see https://www.rfc-editor.org/rfc/rfc9110.html#section-15.2-3

This definition of final :) The last response, which is the first response that's not a 1xx or a 3xx

And do we care about measuring the arrival times of trailer field sections on the final response message?

Perhaps this is a separate conversation, since trailers are not currently widely supported.

LPardue commented 1 year ago

This definition of final :) The last response, which is the first response that's not a 1xx or a 3xx

Great! I support add such timing markers.

Perhaps this is a separate conversation, since trailers are not currently widely supported.

Happy for that to be spun off

colinbendell commented 1 year ago

We should also consider also finalResponseBodyStart time to distinguish header-end and the data payload start

nicjansma commented 1 year ago

Some points from the 9/1 W3C WebPerf call:

tunetheweb commented 1 year ago

To @colinbendell 's point in #181, instead of adding finalXXX timings, we could add the following:

And then also add:

Only thing I don't like about that is we don't have the equivalent opposites (e.g. responseHeadersStart which is basically responseStart) and responseBodyEnd (which is basically responseEnd if you ignore the the little used HTTP Trailers) so might be confusing.

noamr commented 1 year ago

We don't always need equivalent opposites, like with secureConnectionStart. I think that's OK

tunetheweb commented 1 year ago

We don't always need equivalent opposites, like with secureConnectionStart. I think that's OK

Yeah I know, but there we don't have secureConnectionEnd at all (though nothing to stop it being added in future), but here we DO have responseHeadersStart - we just call it something else (responseStart).

Anyway, I'll get over it. Just looks a little odd.

colinbendell commented 1 year ago

I agree with @tunetheweb's proposal. This focuses responseStart and responseEnd to target the whole response of the "final" response code and also preserves legacy interpretations. The added metrics optionally increase the resolution for newer rum providers without burdening these vendors to release patches.

LPardue commented 1 year ago

Please don't prefix anything with early. If we want to support interim HTTP responses, call it that. Expect the HTTP to define more 1xx codes, because its been a part of HTTP since forever.

If we only want to record the time of the first interim response, that fine. But let's be clear. What these events measure. Maybe today first and last interim response are measured at the same time due to fetch. In the future, if fetch changes to support multiple interim responses, our first and last markers would be ready.

tunetheweb commented 1 year ago

We don't always need equivalent opposites, like with secureConnectionStart. I think that's OK

Yeah I know, but there we don't have secureConnectionEnd at all (though nothing to stop it being added in future), but here we DO have responseHeadersStart - we just call it something else (responseStart).

Anyway, I'll get over it. Just looks a little odd.

Though guess you could in theory have a responseBodyEnd before responseEnd (e.g. if considering Trailers), and we're just choosing not to include that now as little need for it as responseEnd is sufficient, in the same way as we're not including secureConnectionEnd. And similarly, theoretically responseHeadersStart could be after responseStart, but again we just won't include it now as little need of it.

tunetheweb commented 1 year ago

Please don't prefix anything with early. If we want to support interim HTTP responses, call it that. Expect the HTTP to define more 1xx codes, because its been a part of HTTP since forever.

If we only want to record the time of the first interim response, that fine. But let's be clear. What these events measure. Maybe today first and last interim response are measured at the same time due to fetch. In the future, if fetch changes to support multiple interim responses, our first and last markers would be ready.

Updated my comment to interimResponseStart instead.

noamr commented 1 year ago

Please don't prefix anything with early. If we want to support interim HTTP responses, call it that. Expect the HTTP to define more 1xx codes, because its been a part of HTTP since forever.

HTTP 103 is defined as "Early Hints", that's where early comes from. 1xx is interim in HTTP lingo, but 103 is early in HTML/fetch/browser lingo. I don't think we want to start measuring other interim responses.

Perhaps earlyHintsStart ?

tunetheweb commented 1 year ago

Perhaps earlyHintsStart ?

I'm against being that specific. Who knows what the future will bring.

noamr commented 1 year ago

Perhaps earlyHintsStart ?

I'm against being that specific. Who knows what the future will bring.

Perhaps when we have new features in the future we find new names for their metrics and be specific about them? If what this feature does currently is early hints, and it's defined in HTTP, perhaps we should be specific?

colinbendell commented 1 year ago

The HTTP spec calls these "Informational" responses (1xx). Should we converge on this language?

tunetheweb commented 1 year ago

Perhaps when we have new features in the future we find new names for their metrics and be specific about them? If what this feature does currently is early hints, and it's defined in HTTP, perhaps we should be specific?

Possibly. Do we measure WebSockets this way? Should interimResponseStart measure when that 101 response comes in, and before the first bytes sent on the WebSocket?

Similarly HTTP/2 also had the upgrade option with 101 before the "final response" was sent, but that was removed from the latest version.

The HTTP spec calls these "Informational" responses (1xx). Should we converge on this language?

I like this.

LPardue commented 1 year ago

Only h2c, as defined in RFC 7540, uses 101. The latest revision of HTTP/2 is RFC 9113, which as Barry points out no longer mentions this feature. In most part because browsers do not implement h2c. We should ignore this.

However 101 for WebSocket upgrade over HTTP/1.1 is an actual thing, we should not ignore it and consider if WebSockets and timings are anything we care about here.

103 Early Hints is defined and is seeing use. And there are use cases for other status codes. For example, 104 is provisionally allocated for resumable upload - newly adopted in the IETF HTTP WG. That specific provisional allocation might fizzle out, but let's be open to supporting the well-defined HTTP extension point of the 1xx status ranges; if we fail to do that job, we damage its future potential.

I disagree with calling things informational responses. RFC 9110 doeant use that term, instead it defines interim responses, which use informational status codes. Terminology needs to be precise and consistent unless there is a good reason to diverge.

Case in point, HTTP as defined in RFC 9110 has moved away from the terms payload and body, and now consistently uses the term "content". Ideally, W3C would align. But I believe due to legacy, that such a change would be disruptive However, new things that we are discussing here have no such legacy.

colinbendell commented 1 year ago

I disagree with calling things informational responses. RFC 9110 doeant use that term, instead it defines interim responses, which use informational status codes. Terminology needs to be precise and consistent unless there is a good reason to diverge.

I'm not sure I follow. Section 15.2 of rfc9110 calls 1xx "informational" class of response codes.

LPardue commented 1 year ago

Status codes are only a piece of a response message, the other pieces include metadata (in the form of field sections) and content. RFC 9110 does not use the term "informational response" anywhere. In contrast it uses the term "interim response" 4 times to describe a non-final response that includes a 1xx( informational) class of status code.

dotjs commented 1 year ago

I'm in favour of using interim as it expresses the non-final and non-authoritative nature of the response. As RFC 9110 states

A single request can have multiple associated responses: zero or more "interim" (non-final) responses with status codes in the "informational" ([1xx] range, followed by exactly one "final" response with a status code in one of the other ranges.

noamr commented 1 year ago

Only h2c, as defined in RFC 7540, uses 101. The latest revision of HTTP/2 is RFC 9113, which as Barry points out no longer mentions this feature. In most part because browsers do not implement h2c. We should ignore this.

However 101 for WebSocket upgrade over HTTP/1.1 is an actual thing, we should not ignore it and consider if WebSockets and timings are anything we care about here.

We currently don't record resource timing for WebSockets at all, but I can see the other points.

The main issue I have with interim/informational is that we might not have interim responses at all (most cases...), and also in some cases we'd have more than one, and this measures only the first one.

How about firstResponseStart (which could be interim or the final one) and responseStart? Otherwise perhaps firstInterimResponseStart and have it be zero if there aren't any. (I don't like having too many zeroes in the resource timing sequence, so not sure it's a favorite)

noamr commented 1 year ago

I posted a PR for the fetch spec. It shouldn't affect the naming bike shed, we can choose the names in the subsequent resource timing PR.

annevk commented 1 year ago

One thing that I'm missing from this thread is a discussion of use cases.

noamr commented 1 year ago

One thing that I'm missing from this thread is a discussion of use cases.

It's been discussed in the WebPerfWG call.

The main use case is that servers who serve early hints and might have latency before serving the final headers/body now don't have visibility as to where this latency lies.

colinbendell commented 1 year ago

There are a few use cases behind the above discussion:

  1. responseStart is previously understood by the industry as 'time-to-first-byte'. Many libraries and rum products in the industry operate with this exception. The strict definition of responseStart breaks the colloquial understanding in the ecosystem.
  2. for use cases where early hints are available, the presence of firstInterimResponseStart will help rum providers and analytics effectively cohort results. This is a current challenge since there is no way to know if the results from clients is an experience where early hints was sent, where early hints were sent and there was >0ms before the http headers arrived or where early hints were not sent.
  3. many frameworks are increasingly returning to http streaming to emit http headers early while the backend continues to process and compose the body. Having responseBodyStart will help segment and cohort experiences in the same way that use case {2} identifies.
LPardue commented 1 year ago

Something that might be worth noting (if not already covered) is that in some scenarios, the checkpoints could appear to have the same values at the client, even if sent and different times on the server. This is especially noticeable if the client has large TCP receive windows and reads a "batch" of data after letting it accumulate for a little while.

noamr commented 1 year ago

This is now implemented in chrome behind a flag (ResourceTimingInterimResponseTimes):

It applies to resource timing, but probably only useful for navigation timing entries. I would like to enable this by default soon.

annevk commented 1 year ago

@noamr is there a follow-up bug for the other two timing channels or should this be reopened?

noamr commented 1 year ago

@noamr is there a follow-up bug for the other two timing channels or should this be reopened?

Oh this shouldn't have been closed, I changed from "Closes" to "Bug".