Skip to content
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

Add finalResponseHeadersStart docs #37740

Merged
merged 4 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions files/en-us/glossary/time_to_first_byte/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
sideshowbarker marked this conversation as resolved.
Show resolved Hide resolved

## 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)
Original file line number Diff line number Diff line change
@@ -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.
sideshowbarker marked this conversation as resolved.
Show resolved Hide resolved

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 to the browser to start receive the final response after the sending the request.
sideshowbarker marked this conversation as resolved.
Show resolved Hide resolved

```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 shnows how to measure the time between the first and final response headers.
sideshowbarker marked this conversation as resolved.
Show resolved Hide resolved

```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")}}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -83,3 +85,4 @@ Timing-Allow-Origin: https://developer.mozilla.org
## See also

- {{HTTPHeader("Timing-Allow-Origin")}}
- {{domxref("PerformanceResourceTiming.finalResponseHeadersStart", "finalResponseHeadersStart")}}
6 changes: 4 additions & 2 deletions files/en-us/web/api/performanceresourcetiming/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`)
Expand Down Expand Up @@ -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.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading