This specification enables a server to communicate performance metrics about the request-response cycle to the user agent. It also standardizes a JavaScript interface to enable applications to collect, process, and act on these metrics to optimize application delivery.
### The `Server-Timing` Header Field
The Server-Timing header field is used to communicate one or more metrics and descriptions for the given request-response cycle. The ABNF (Augmented Backus-Naur Form) [[RFC5234]] syntax for the [=Server-Timing header field=] is as follows:
```ABNF
Server-Timing = #server-timing-metric
server-timing-metric = metric-name *( OWS ";" OWS server-timing-param )
metric-name = token
server-timing-param = server-timing-param-name OWS "=" OWS server-timing-param-value
server-timing-param-name = token
server-timing-param-value = token / quoted-string
```
See [[RFC7230]] for definitions of `#`, `*`, `OWS`, `token`, and `quoted-string`.
A response MAY have multiple server-timing-metric entries with the same metric-name, and the user agent MUST process and expose all such entries.
The user agent MAY surface provided metrics in any order - i.e. the order of metrics in the HTTP header field is not significant.
This header field is defined with an extensible syntax to allow for future parameters. A user agent that does not recognize particular server-timing-param-name in the Server-Timing header field of a response MUST ignore those tokens and continue processing instead of signaling an error.
To avoid any possible ambiguity, individual `server-timing-param-name`s SHOULD NOT appear multiple times within a `server-timing-metric`. If any `server-timing-param-name` is specified more than once, only the first instance is to be considered, even if the `server-timing-param` is incomplete or invalid. All subsequent occurrences MUST be ignored without signaling an error or otherwise altering the processing of the `server-timing-metric`. This is the only case in which the ordering of parameters within a `server-timing-metric` is considered to be significant.
User agents MUST ignore extraneous characters found after a `server-timing-param-value` but before the next `server-timing-param` and before the end of the current `server-timing-metric`.
User agents MUST ignore extraneous characters found after a `metric-name` but before the first `server-timing-param` and before the next `server-timing-metric`.
This specification establishes the server-timing-params for server-timing-param-names "dur" for {{duration}} and "desc" for {{description}}, both optional.
- To minimize the HTTP overhead the provided names and descriptions should be kept as short as possible - e.g. use abbreviations and omit optional values where possible.
- Because there can be no guarantee of clock synchronization between client, server, and intermediaries, it is impossible to map a meaningful `startTime` onto the clients timeline. For that reason, any `startTime` attribution is purposely omitted from this specification. If the developers want to establish a relationship between multiple entries, they can do so by communicating custom data via metric names and/or descriptions.
- The server and/or any relevant intermediaries are in full control of which metrics are communicated to the user agent and when. For example, access to some metrics may be restricted due to privacy or security reasons - see
section.
## The PerformanceServerTiming Interface
``` webidl
[Exposed=(Window,Worker)]
interface PerformanceServerTiming {
readonly attribute DOMString name;
readonly attribute DOMHighResTimeStamp duration;
readonly attribute DOMString description;
[Default] object toJSON();
};
```
When toJSON is called, run [[WEBIDL]]'s [=default toJSON steps=].
### name attribute
The {{name}} attribute MUST return the DOMString value of the server-specified metric name.
### duration attribute
The {{duration}} attribute MUST return a double that contains the server-specified metric duration, or value `0.0`.
### description attribute
The {{description}} attribute MUST return the DOMString value of the server-specified metric description, or an empty string.
### Extension to the {{PerformanceResourceTiming}} interface
The PerformanceResourceTiming interface, which this specification partially extends, is defined in [[RESOURCE-TIMING-2]].
``` webidl
[Exposed=(Window,Worker)]
partial interface PerformanceResourceTiming {
readonly attribute FrozenArray<PerformanceServerTiming> serverTiming;
};
```
### serverTiming attribute
The {{serverTiming}} attribute returns a sequence of {{PerformanceServerTiming}} entries.
## Process
### Processing Model
When processing the response of the current document, set the {{PerformanceResourceTiming/serverTiming}} attribute on the newly created `PerformanceNavigationTiming` object to the return value of the [=server-timing header parsing algorithm=]
For each resource [= fetch | fetched =] by the current [=browsing context=], excluding resources fetched by cross-origin stylesheets fetched with `no-cors` policy, set the {{PerformanceResourceTiming/serverTiming}} attribute on the newly created {{PerformanceResourceTiming}} object to:
- An empty [=sequence=], if the return value from the "timing allow check" algorithm (as defined in [[RESOURCE-TIMING-2]]) is `fail`.
- An empty [=sequence=], if the user agent chooses to limit their support to [=secure contexts=] and the current document's [=environment settings object=] is not contextually secure.
- The return value of the [=server-timing header parsing algorithm=], otherwise.
#### server-timing header parsing algorithm
Given a |resource timing object|, perform the following steps:
- Let |entryList| be a new empty [=sequence=].
- For each server-specified metric received from parsing the [=Server-Timing header field=], perform the following steps:
- Let |entry:PerformanceServerTiming| be a new {{PerformanceServerTiming}} object.
- Set {{name}} to metric-name.
- Set {{duration}} to the server-timing-param-value for the server-timing-param where server-timing-param-name is case-insensitively equal to "dur", or value 0 if omitted or not representable as a double.
- Set {{description}} to the server-timing-param-value for the server-timing-param where server-timing-param-name is case-insensitively equal to "desc", or an empty string if omitted.
- Append |entry| to |entryList|.
- Return |entryList|
The user-agent MAY process [=Server-Timing header field=] communicated via a trailer field (see [[RFC7230]] section 4.1.2) using the same algorithm.
## IANA Considerations
The permanent message header field registry should be updated with the following registrations ([[RFC3864]]):
### Server-Timing Header Field
- Header field name
- Server-Timing
- Applicable protocol
- http
- Status
- standard
- Author/Change controller
- W3C
- Specification document
- This specification (See [=Server-Timing Header Field=])