diff --git a/files/en-us/glossary/time_to_first_byte/index.md b/files/en-us/glossary/time_to_first_byte/index.md index af1e0a5afb123b5..76f6eccbcc6fede 100644 --- a/files/en-us/glossary/time_to_first_byte/index.md +++ b/files/en-us/glossary/time_to_first_byte/index.md @@ -8,14 +8,17 @@ page-type: glossary-definition **Time to First Byte** (TTFB) refers to the time between the browser requesting a page and when it receives the first byte of information from the server. This time includes {{Glossary("DNS")}} lookup and establishing the connection using a {{Glossary("TCP")}} handshake and {{Glossary("TLS")}} handshake if the request is made over {{Glossary("HTTPS")}}. -TTFB is the time it takes between the start of the request and the start of the response, in milliseconds: +TTFB is the time it takes between the start of the request and the start of the response, in milliseconds. This can be measured using the `{{domxref("PerformanceResourceTiming.requestStart", "requestStart")}}` attribute of {{domxref("PerformanceNavigationTiming")}}: -```plain -TTFB = responseStart - navigationStart +```javascript +const ttfb = performance.getEntriesByType("navigation")[0].responseStart; ``` +> [!NOTE] +> For sites using {{HTTPStatus("103", "103 Early Hints")}}, TTFB is typically the _first bytes_ (after any redirects) — and so, the 103 interim response. Site owners wishing to measure the time until the final response should use `{{domxref("PerformanceResourceTiming.finalResponseHeadersStart", "finalResponseHeadersStart")}}`, where supported. + ## See also - [A typical HTTP session](/en-US/docs/Web/HTTP/Session) - [PerformanceResourceTiming](/en-US/docs/Web/API/PerformanceResourceTiming) -- [PerformanceTiming](/en-US/docs/Web/API/PerformanceTiming) +- [PerformanceNavigationTiming](/en-US/docs/Web/API/PerformanceNavigationTiming) diff --git a/files/en-us/web/api/performanceresourcetiming/finalresponseheadersstart/index.md b/files/en-us/web/api/performanceresourcetiming/finalresponseheadersstart/index.md new file mode 100644 index 000000000000000..e2b50bc672699c1 --- /dev/null +++ b/files/en-us/web/api/performanceresourcetiming/finalresponseheadersstart/index.md @@ -0,0 +1,103 @@ +--- +title: "PerformanceResourceTiming: finalResponseHeadersStart property" +short-title: finalResponseHeadersStart +slug: Web/API/PerformanceResourceTiming/finalResponseHeadersStart +page-type: web-api-instance-property +status: + - experimental +browser-compat: api.PerformanceResourceTiming.finalResponseHeadersStart +--- + +{{APIRef("Performance API")}}{{AvailableInWorkers}}{{SeeCompatTable}} + +The **`finalResponseHeadersStart`** read-only property returns a {{domxref("DOMHighResTimeStamp","timestamp")}} immediately after the browser receives the first byte of the final document response (for example, 200 OK) from the server. + +This differs from **`{{domxref("PerformanceResourceTiming.requestStart", "requestStart")}}`** (which may also be represented as **`{{domxref("PerformanceResourceTiming.firstInterimResponseStart", "firstInterimResponseStart")}}`**), as this starts from the first bytes of any response including interim responses (for example, 103 Early Hints) with the final response coming potentially much later. + +When there are no interim responses, `requestStart` is the same as `finalResponseHeadersStart` and `firstInterimResponseStart` is 0. + +There is no _end_ property for `finalResponseHeadersStart`. + +## Value + +The `finalResponseHeadersStart` property can have the following values: + +- A {{domxref("DOMHighResTimeStamp")}} immediately after the browser receives the first bytes of the final response from the server. +- `0` if the resource is a cross-origin request and no {{HTTPHeader("Timing-Allow-Origin")}} HTTP response header is used. + +## Examples + +### Measuring request time + +The `finalResponseHeadersStart` and {{domxref("PerformanceResourceTiming.requestStart", "requestStart")}} properties can be used to measure how long it takes for the browser to start receive the final response after the sending the request. + +```js +const request = entry.finalResponseHeadersStart - entry.requestStart; +``` + +The following example uses a {{domxref("PerformanceObserver")}} to notify of new `resource` performance entries as they are recorded in the browser's performance timeline. The `buffered` option is used for accessing entries from before the observer creation. + +```js +const observer = new PerformanceObserver((list) => { + list.getEntries().forEach((entry) => { + const request = entry.finalResponseHeadersStart - entry.requestStart; + if (request > 0) { + console.log(`${entry.name}: final response time: ${request}ms`); + } + }); +}); + +observer.observe({ type: "resource", buffered: true }); +``` + +The following example uses {{domxref("Performance.getEntriesByType()")}}, which only shows `resource` performance entries present in the browser's performance timeline at the time you call the method. + +```js +const resources = performance.getEntriesByType("resource"); +resources.forEach((entry) => { + const request = entry.finalResponseHeadersStart - entry.requestStart; + if (request > 0) { + console.log(`${entry.name}: final response time: ${request}ms`); + } +}); +``` + +The following example shows how to measure the time between the first and final response headers. + +```js +const observer = new PerformanceObserver((list) => { + list.getEntries().forEach((entry) => { + const diff = entry.finalResponseHeadersStart - entry.responseStart; + if ((entry.finalResponseHeadersStart > 0) & (diff > 0)) { + console.log( + `${entry.name}: time between first and final response start: ${diff}ms`, + ); + } + }); +}); + +observer.observe({ type: "resource", buffered: true }); +``` + +### Cross-origin timing information + +If the value of the `finalResponseHeadersStart` property is `0`, the resource might be a cross-origin request. To allow seeing cross-origin timing information, the {{HTTPHeader("Timing-Allow-Origin")}} HTTP response header needs to be set. + +For example, to allow `https://developer.mozilla.org` to see timing resources, the cross-origin resource should send: + +```http +Timing-Allow-Origin: https://developer.mozilla.org +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{HTTPHeader("Timing-Allow-Origin")}} +- {{domxref("PerformanceResourceTiming.firstInterimResponseStart", "firstInterimResponseStart")}} diff --git a/files/en-us/web/api/performanceresourcetiming/firstinterimresponsestart/index.md b/files/en-us/web/api/performanceresourcetiming/firstinterimresponsestart/index.md index d1b7fbad836b6ae..d097f6d92a02195 100644 --- a/files/en-us/web/api/performanceresourcetiming/firstinterimresponsestart/index.md +++ b/files/en-us/web/api/performanceresourcetiming/firstinterimresponsestart/index.md @@ -19,17 +19,19 @@ There is no _end_ property for `firstInterimResponseStart`. The `firstInterimResponseStart` property can have the following values: - A {{domxref("DOMHighResTimeStamp")}} immediately after the browser receives the first interim bytes of the response from the server. -- `0` if the resource sent no interim response +- `0` if the resource sent no interim response. - `0` if the resource is a cross-origin request and no {{HTTPHeader("Timing-Allow-Origin")}} HTTP response header is used. > [!NOTE] > As Early Hints are typically only supported on the main navigation request, which is by definition same-origin, a `0` typically indicates Early Hints were **not** used. +When the `firstInterimResponseStart` is non-zero, that indicates it should be the same value as {{domxref("PerformanceResourceTiming.requestStart", "requestStart")}} for [supporting browsers](#browser_compatibility). + ## Examples ### Measuring request time -The `firstInterimResponseStart` and {{domxref("PerformanceResourceTiming.requestStart", "requestStart")}} properties can be used to measure how long it takes to the browser to receive an interim response after the sending the request. +The `firstInterimResponseStart` and `requestStart` properties can be used to measure how long it takes to the browser to receive an interim response after the sending the request. ```js const request = entry.firstInterimResponseStart - entry.requestStart; @@ -83,3 +85,4 @@ Timing-Allow-Origin: https://developer.mozilla.org ## See also - {{HTTPHeader("Timing-Allow-Origin")}} +- {{domxref("PerformanceResourceTiming.finalResponseHeadersStart", "finalResponseHeadersStart")}} diff --git a/files/en-us/web/api/performanceresourcetiming/index.md b/files/en-us/web/api/performanceresourcetiming/index.md index 21840e5fa9bd8af..dcd14d2ab1b90a2 100644 --- a/files/en-us/web/api/performanceresourcetiming/index.md +++ b/files/en-us/web/api/performanceresourcetiming/index.md @@ -22,7 +22,7 @@ The properties of this interface allow you to calculate certain resource timing - Measuring TCP handshake time (`connectEnd` - `connectStart`) - Measuring DNS lookup time (`domainLookupEnd` - `domainLookupStart`) - Measuring redirection time (`redirectEnd` - `redirectStart`) -- Measuring interim request time (`firstInterimResponseStart` - `requestStart`) +- Measuring interim request time (`firstInterimResponseStart` - `finalResponseHeadersStart`) - Measuring request time (`responseStart` - `requestStart`) - Measuring TLS negotiation time (`requestStart` - `secureConnectionStart`) - Measuring time to fetch (without redirects) (`responseEnd` - `fetchStart`) @@ -76,7 +76,9 @@ The interface supports the following timestamp properties which you can see in t - {{domxref('PerformanceResourceTiming.firstInterimResponseStart')}} {{experimental_inline}} {{ReadOnlyInline}} - : A {{domxref("DOMHighResTimeStamp")}} that represents the interim response time (for example, 100 Continue or 103 Early Hints). - {{domxref('PerformanceResourceTiming.responseStart')}} {{ReadOnlyInline}} - - : A {{domxref("DOMHighResTimeStamp")}} immediately after the browser receives the first byte of the response from the server. + - : A {{domxref("DOMHighResTimeStamp")}} immediately after the browser receives the first byte of the response from the server (which may be an interim response). +- {{domxref('PerformanceResourceTiming.finalResponseHeadersStart')}} {{experimental_inline}} {{ReadOnlyInline}} + - : A {{domxref("DOMHighResTimeStamp")}} that represents the final headers response time (for example, 200 Success), after any interim response time. - {{domxref('PerformanceResourceTiming.responseEnd')}} {{ReadOnlyInline}} - : A {{domxref("DOMHighResTimeStamp")}} immediately after the browser receives the last byte of the resource or immediately before the transport connection is closed, whichever comes first. diff --git a/files/en-us/web/api/performanceresourcetiming/requeststart/index.md b/files/en-us/web/api/performanceresourcetiming/requeststart/index.md index 9aed4c8621dac18..ca973324432f798 100644 --- a/files/en-us/web/api/performanceresourcetiming/requeststart/index.md +++ b/files/en-us/web/api/performanceresourcetiming/requeststart/index.md @@ -20,6 +20,10 @@ The `requestStart` property can have the following values: - `0` if the resource was instantaneously retrieved from a cache. - `0` if the resource is a cross-origin request and no {{HTTPHeader("Timing-Allow-Origin")}} HTTP response header is used. +When the `firstInterimResponseStart` is non-zero, that indicates it should be the same value as {{domxref("PerformanceResourceTiming.requestStart", "requestStart")}} for [supporting browsers](#browser_compatibility). + +When there are no interim responses, `requestStart` is the same as `finalResponseHeadersStart` and `firstInterimResponseStart` is 0. + ## Examples ### Measuring request time