Copyright © 2019 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and permissive document license rules apply.
This specification defines an interface for web applications to access the complete timing information for resources in a document.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.
Implementers SHOULD be aware that this document is not stable. Implementers who are not taking part in the discussions are likely to find the specification changing out from under them in incompatible ways. Vendors interested in implementing this document before it eventually reaches the Candidate Recommendation stage SHOULD join the aforementioned mailing lists and take part in the discussions.
This document was published by the Web Performance Working Group as a Working Draft. This document is intended to become a W3C Recommendation.
GitHub Issues are preferred for
discussion of this specification.
Alternatively, you can send comments to our mailing list.
Please send them to
public-web-perf@w3.org
(archives)
with [ResourceTiming]
at the start of your
email's subject
.
Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was produced by a group operating under the W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
This document is governed by the 1 March 2019 W3C Process Document.
This section is non-normative.
User latency is an important quality benchmark for Web
Applications. While JavaScript-based mechanisms can provide
comprehensive instrumentation for user latency measurements within
an application, in many cases, they are unable to provide a
complete end-to-end latency picture. This document introduces the
PerformanceResourceTiming
interface to allow JavaScript
mechanisms to collect complete timing information related to
resources on a document. Navigation Timing 2
[NAVIGATION-TIMING-2] extends this specification to provide
additional timing information associated with a navigation.
For example, the following JavaScript shows a simple attempt to measure the time it takes to fetch a resource:
<!doctype html>
<html>
<head>
</head>
<body onload="loadResources()">
<script>
function loadResources()
{
var start = new Date().getTime();
var image1 = new Image();
var resourceTiming = function() {
var now = new Date().getTime();
var latency = now - start;
alert("End to end resource fetch: " + latency);
};
image1.onload = resourceTiming;
image1.src = 'https://www.w3.org/Icons/w3c_main.png';
}
</script>
<img src="https://www.w3.org/Icons/w3c_home.png">
</body>
</html>
Though this script can measure the time it takes to fetch a resource, it cannot break down the time spent in various phases. Further, the script cannot easily measure the time it takes to fetch resources described in markup.
To address the need for complete information on user experience,
this document introduces the PerformanceResourceTiming
interface. This interface allows JavaScript mechanisms to provide
complete client-side latency measurements within applications. With
this interface, the previous example can be modified to measure a
user's perceived load time of a resource.
The following script calculates the amount of time it takes to
fetch every resource in the page, even those defined in markup.
This example assumes that this page is hosted on
https://www.w3.org. One could further measure the amount of time it
takes in every phase of fetching a resource with the
PerformanceResourceTiming
interface.
<!doctype html>
<html>
<head>
</head>
<body onload="loadResources()">
<script>
function loadResources()
{
var image1 = new Image();
image1.onload = resourceTiming;
image1.src = 'https://www.w3.org/Icons/w3c_main.png';
}
function resourceTiming()
{
var resourceList = window.performance.getEntriesByType("resource");
for (i = 0; i < resourceList.length; i++)
{
if (resourceList[i].initiatorType == "img")
{
alert("End to end resource fetch: " + (resourceList[i].responseEnd - resourceList[i].startTime));
}
}
}
</script>
<img id="image0" src="https://www.w3.org/Icons/w3c_home.png">
</body>
</html>
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MAY, MUST, MUST NOT, SHOULD, and SHOULD NOT are to be interpreted as described in [RFC2119].
Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("MUST", "SHOULD", "MAY", etc) used in introducing the algorithm.
Some conformance requirements are phrased as requirements on attributes, methods or objects. Such requirements are to be interpreted as requirements on user agents.
Conformance requirements phrased as algorithms or specific steps may be implemented in any manner, so long as the end result is equivalent. (In particular, the algorithms defined in this specification are intended to be easy to follow, and not intended to be performant.)
The construction "a Foo
object", where
Foo
is actually an interface, is sometimes used
instead of the more accurate "an object implementing the interface
Foo
.
The term DOM is used to refer to the API set made available to scripts in Web applications, and does not necessarily imply the existence of an actual Document object or of any other Node objects as defined in the [DOM] specification.
A DOM attribute is said to be getting when its value is being retrieved (such as by author script), and is said to be setting when a new value is assigned to it.
The term JavaScript is used to refer to ECMA262, rather than the official term ECMAScript, since the term JavaScript is more widely known. [ECMASCRIPT]
The term resource is used to refer to elements and any other user-initiated fetches throughout this specification. For example, a resource could originate from XMLHttpRequest objects [XHR], HTML elements [HTML] such as iframe, img, script, object, embed, and link with the link type of stylesheet, and SVG elements [SVG11] such as svg.
The term cross-origin is used to mean non same origin.
The term current document refers to the document associated with the Window object's newest Document object.
Throughout this work, all time values are measured in milliseconds since the start of navigation of the document [HR-TIME-2]. For example, the start of navigation of the document occurs at time 0.
The term current time refers to the number of milliseconds since the start of navigation of the document until the current moment in time.
This definition of time is based on the High Resolution Time specification [HR-TIME-2] and is different from the definition of time used in the Navigation Timing specification [NAVIGATION-TIMING-2], where time is measured in milliseconds since midnight of January 1, 1970 (UTC).
This section is non-normative.
The PerformanceResourceTiming
interface facilitates
timing measurement of downloadable resources. For example, this
interface is available for XMLHttpRequest objects [XHR],
HTML elements [HTML] such as iframe, img, script, object, embed, and link with the link type of
stylesheet, and SVG
elements [SVG11] such as svg.
PerformanceResourceTiming
InterfaceAll resource Requests
fetched by a non-null client MUST be included as
PerformanceResourceTiming
objects in the client's global object's
Performance
Timeline, unless excluded from the timeline as part of the processing model.
Resources that are retrieved from
relevant
application caches or local resources MUST be included as
PerformanceResourceTiming
objects in the Performance
Timeline [PERFORMANCE-TIMELINE-2]. Resources for which the
fetch was initiated, but was
later aborted (e.g. due to a network error) MAY be included as
PerformanceResourceTiming
objects in the Performance
Timeline and MUST contain initialized attribute values for
processed substeps of the processing
model.
The rest of this section is non-normative.
Examples:
src
attribute of two HTML IMG
elements, the fetch of the resource initiated by the
first HTML IMG
element SHOULD be included as a
PerformanceResourceTiming
object in the Performance
Timeline. The user agent might not re-request the URL for the
second HTML IMG
element, instead using the existing
download it initiated for the first HTML IMG
element.
In this case, the fetch of
the resource by the first IMG
element would be the
only occurrence in the Performance
Timeline.src
attribute of a HTML IMG
element is changed via script, both the fetch of the original resource as well as
the fetch of the new URL
would be included as PerformanceResourceTiming
objects in
the Performance
Timeline.IFRAME
element is added via markup
without specifying a src
attribute, the user agent may
load the about:blank
document for the
IFRAME
. If at a later time the src
attribute is changed dynamically via script, the user agent may
fetch the new URL resource
for the IFRAME
. In this case, only the fetch of the new URL would be included as
a PerformanceResourceTiming
object in the Performance
Timeline.XMLHttpRequest
is generated twice for the
same canonical URL, both fetches of the resource would be included
as a PerformanceResourceTiming
object in the Performance
Timeline. This is because the fetch of the resource for the second
XMLHttpRequest
cannot reuse the download issued for
the first XMLHttpRequest
.IFRAME
element is included on the page,
then only the resource requested by IFRAME
src
attribute is included as a
PerformanceResourceTiming
object in the Performance
Timeline. Sub-resources requested by the IFRAME
document will be included in the IFRAME
document's
Performance
Timeline and not the parent document's Performance
Timeline.IMG
element has a data: URI
as its
source [RFC2397], then this resource will not be included as a
PerformanceResourceTiming
object in the Performance
Timeline. By definition data: URI
contains
embedded data and does not require a fetch.PerformanceResourceTiming
object in the Performance
Timeline with initialized attribute values up to the point of
failure - e.g. a TCP handshake error should report DNS timestamps
for the request, and so on.PerformanceResourceTiming
object in the
Performance
Timeline.PerformanceResourceTiming
InterfaceThe PerformanceResourceTiming
interface participates in
the Performance
Timeline and extends the following attributes of the
PerformanceEntry
interface:
resource
".redirectStart
.
Otherwise, this attribute MUST return the same value as
fetchStart
.responseEnd
and startTime,
respectively.[Exposed=(Window,Worker)]
interface PerformanceResourceTiming
: PerformanceEntry
{
readonly attribute DOMString initiatorType
;
readonly attribute DOMString nextHopProtocol
;
readonly attribute DOMHighResTimeStamp workerStart
;
readonly attribute DOMHighResTimeStamp redirectStart
;
readonly attribute DOMHighResTimeStamp redirectEnd
;
readonly attribute DOMHighResTimeStamp fetchStart
;
readonly attribute DOMHighResTimeStamp domainLookupStart
;
readonly attribute DOMHighResTimeStamp domainLookupEnd
;
readonly attribute DOMHighResTimeStamp connectStart
;
readonly attribute DOMHighResTimeStamp connectEnd
;
readonly attribute DOMHighResTimeStamp secureConnectionStart
;
readonly attribute DOMHighResTimeStamp requestStart
;
readonly attribute DOMHighResTimeStamp responseStart
;
readonly attribute DOMHighResTimeStamp responseEnd
;
readonly attribute unsigned long long transferSize
;
readonly attribute unsigned long long encodedBodySize
;
readonly attribute unsigned long long decodedBodySize
;
[Default] object toJSON
();
};
When toJSON
is called, run [WEBIDL]'s default toJSON operation.
On getting, the
initiatorType
attribute MUST return one of the following
DOMString
values:
localName
of that
element
[DOM], if the request is a result of processing the
element
;url()
directive
[CSS-SYNTAX-3], such as @import url()
or
background: url()
;On getting, the
attribute nextHopProtocol
returns the network protocol
used to fetch the resource, as identified by the ALPN Protocol ID
[RFC7301]; resources retrieved from relevant application caches
or local resources, return an empty string. When a proxy is
configured, if a tunnel connection is established then this
attribute MUST return the ALPN Protocol ID of the tunneled
protocol, otherwise it MUST return the ALPN Protocol ID of the
first hop to the proxy. In order to have precisely one way to
represent any ALPN protocol ID, the following additional
constraints apply: octets in the ALPN protocol MUST NOT be
percent-encoded if they are valid token characters except "%", and
when using percent-encoding, uppercase hex digits MUST be used.
Formally registered ALPN protocol IDs are documented by IANA. In case the user agent is using an experimental, non-registered protocol, the user agent MUST use the ALPN negotiated value if any. If ALPN was not used for protocol negotiations, the user agent MAY use another descriptive string.
The "h3" ALPN ID is defined for the final version of the HTTP/3 protocol in the HTTP/3 Internet Draft.
Note that the nextHopProtocol
attribute is
intended to identify the network protocol in use for the fetch
regardless of how it was actually negotiated; that is, even if ALPN
is not used to negotiate the network protocol, this attribute still
uses the ALPN Protocol ID's to indicate the protocol in use.
On getting, the
workerStart
attribute MUST return as follows:
If the current browsing or worker context's have an active worker [service-workers-1]:
Note that according to the definition of time origin in workers, it is possible that some attributes of navigation preload requests will have negative DOMHighResTimeStamp values.
On getting, the
redirectStart
attribute MUST return as follows:
On getting, the
redirectEnd
attribute MUST return as follows:
On getting, the
fetchStart
attribute MUST return as follows:
On getting, the
domainLookupStart
attribute MUST return as follows:
fetchStart
, if no domain lookup was
required to fetch the resources (e.g. if a persistent
connection [RFC7230] was used or in case the resource was
retrieved from relevant
application caches or local resources).On getting, the
domainLookupEnd
attribute MUST return as follows:
fetchStart
, if no domain lookup was
required to fetch the resources (e.g. if a persistent
connection [RFC7230] was used or in case the resource was
retrieved from relevant
application caches or local resources).On getting, the
connectStart
attribute MUST return as follows:
fetchStart
, if a persistent connection [RFC7230] is used
or the resource is retrieved from relevant application caches or
local resources.If the transport connection fails and the user agent reopens a
connection, connectStart
SHOULD return the
corresponding value of the new connection.
On getting, the
connectEnd
attribute MUST return as follows:
fetchStart
, if a persistent connection [RFC7230] is used
or the resource is retrieved from relevant application caches
or local resources.The returned time MUST include the time interval to establish the transport connection, as well as other time intervals such as SSL handshake and SOCKS authentication.
If the transport connection fails and the user agent reopens a
connection, connectEnd
SHOULD return the
corresponding value of the new connection.
On getting, the
secureConnectionStart
attribute MUST return as
follows:
fetchStart
, if a persistent connection [RFC7230] is used
or the resource is retrieved from relevant application caches
or local resources.On getting, the
requestStart
attribute MUST return as follows:
If the transport connection fails after a request is sent and
the user agent reopens a connection and resend the request,
requestStart
MUST
return the corresponding values of the new request.
On getting, the
responseStart
attribute MUST return as follows:
On getting, the
responseEnd
attribute MUST return as follows:
On getting, the
transferSize
attribute MUST return as follows:
If there are HTTP redirects or equivalent when navigating and if all the redirects or equivalent are same origin, this attribute SHOULD include the HTTP overhead of incurred redirects.
This attribute SHOULD include HTTP overhead (such as HTTP/1.1 chunked encoding and whitespace around header fields, including newlines, and HTTP/2 frame overhead, along with other server-to-client frames on the same stream), but SHOULD NOT include lower-layer protocol overhead (such as TLS [RFC5246]or TCP).
On getting, the
encodedBodySize
attribute MUST return as follows:
On getting, the
decodedBodySize
attribute MUST return as follows:
A user agent implementing PerformanceResourceTiming
MUST run the
register a performance entry type algorithm with "resource"
as
input.
Performance
InterfaceThe user agent MAY choose to limit how many resources are
included as PerformanceResourceTiming
objects in the
Performance
Timeline [PERFORMANCE-TIMELINE-2]. This section extends the
Performance
interface to allow controls over the number of
PerformanceResourceTiming
objects stored.
The recommended minimum number of
PerformanceResourceTiming
objects is 250, though this may be
changed by the user agent. setResourceTimingBufferSize
can be called to
request a change to this limit.
Each ECMAScript global environment has:
PerformanceResourceTiming
objects that is initially empty.partial interface Performance
{
void clearResourceTimings
();
void setResourceTimingBufferSize
(unsigned long maxSize);
attribute EventHandler onresourcetimingbufferfull
;
};
The Performance
interface is defined in
[HR-TIME-2].
The method clearResourceTimings
runs the following
steps:
PerformanceResourceTiming
objects in the
performance
entry buffer.The setResourceTimingBufferSize
method runs the
following steps:
PerformanceResourceTiming
objects are to be removed from the
performance
entry buffer.The attribute onresourcetimingbufferfull
is the event
handler for the resourcetimingbufferfull event described
below.
To check if can add resource timing entry, run the following steps:
To add a PerformanceResourceTiming entry into the performance entry buffer, run the following steps:
PerformanceEntry
to be added.
To copy secondary buffer, run the following steps:
PerformanceResourceTiming
in
resource timing secondary buffer.To fire a buffer full event, run the following steps:
resourcetimingbufferfull
at the Performance object.This means that if the resourcetimingbufferfull
event handler does not add more room in the buffer than it adds resources to
it, excess entries will be dropped from the buffer. Developers should make sure
that resourcetimingbufferfull
event handlers call
clearResourceTimings
or extend the buffer sufficiently (by calling
setResourceTimingBufferSize
).
Cross-origin resources
MUST be included as PerformanceResourceTiming
objects in the
Performance
Timeline. If the timing allow check algorithm fails for
a resource, these attributes of its PerformanceResourceTiming
object MUST be set to zero:
redirectStart
, redirectEnd
, domainLookupStart
,
domainLookupEnd
, connectStart
, connectEnd
,
requestStart
, responseStart
,
secureConnectionStart
, transferSize
,
encodedBodySize
and decodedBodySize
.
Server-side applications may return the Timing-Allow-Origin HTTP response header to allow the User Agent to fully expose, to the document origin(s) specified, the values of attributes that would have been zero due to the cross-origin restrictions previously specified in this section.
Timing-Allow-Origin
Response HeaderThe Timing-Allow-Origin HTTP response header field can be used to communicate a policy indicating origin(s) that are allowed to see values of attributes that would have been zero due to the cross-origin restrictions. The header's value is represented by the following ABNF [RFC5234] (using List Extension, [RFC7230]):
Timing-Allow-Origin = 1#( origin-or-null / wildcard )
The sender MAY generate multiple Timing-Allow-Origin header fields. The recipient MAY combine multiple Timing-Allow-Origin header fields by appending each subsequent field value to the combined field value in order, separated by a comma.
The timing allow check algorithm, which checks whether a resource's timing information can be shared with the current document, is as follows:
If the resource's Request's window is not an environment
settings object, return fail
.
For each request in the resource fetch redirection-chain:
If request's origin is same-origin when compared to the resource's Request's window's origin, continue to the next request.
If the Timing-Allow-Origin header value list
does not contain a value which is byte-for-byte identical to
the serialization
of the current document's origin, nor a
wildcard ("*
"), return fail
.
Return pass
.
The above definition does not fully align Timing-Allow-Origin's processing with CORS processing. Specifically, if a redirection chain includes a cross-origin resource followed by same-origin resources without an explicit opt-in, TAO will pass while CORS will fail. Future iterations of this specification may attempt to unite those definitions.
This section registers Timing-Allow-Origin as a Provisional Message Header.
Timing-Allow-Origin
The following graph illustrates the timing attributes defined by the PerformanceResourceTiming interface. Attributes in parenthesis may not be available when fetching cross-origin resources. User agents may perform internal processing in between timings, which allow for non-normative intervals between timings.
For each resource whose Request has a non-null client, perform the following steps:
no-cors
policy,
abort the remaining steps.
Above cross-origin exclusion should be defined via Fetch registry: CSS needs to be defined in terms of Fetch and set some kind of "opaque request flag" for no-CORS CSS subresources. In turn, Resource Timing should interface with Fetch registry to surface resource fetch events.
The above resource exclusion is at risk as currently only one implementation passes the related test.
PerformanceResourceTiming
object and set
entryType to the DOMString resource
.nextHopProtocol
to the empty DOMString.initiatorType
.workerStart
, or if the worker is already
available, immediately before the event named `fetch`
is fired at the active worker record the time as
workerStart
. Otherwise, if there is no matching
service
worker registration, set workerStart
value to zero.fetchStart
. Let domainLookupStart
,
domainLookupEnd
, connectStart
and connectEnd
be the same value as fetchStart
.redirectStart
, redirectEnd
,
domainLookupStart
, domainLookupEnd
, connectStart
,
connectEnd
, requestStart
, responseStart
and
secureConnectionStart
to zero and go to the step labeled response end.domainLookupStart
, domainLookupEnd
,
connectStart
and connectEnd
be the same value as
fetchStart
.domainLookupStart
.domainLookupEnd
immediately after the
domain name lookup is successfully done. A user agent may need
multiple retries before that. If the domain name lookup fails and
resource passes the timing allow check record the time as
domainLookupEnd
and go to the step labeledfinal record.connectStart
and connectEnd
be the same value of domainLookupEnd
. Otherwise, record the
time as connectStart
immediately before initiating a successful
connection to the server and record the time as connectEnd
immediately after the successful connection to the server or proxy is
established. A user agent may need multiple retries to establish a
successful connection and should reflect the timestamps for the
successful connection only.
Once connection is established set the value of nextHopProtocol
to the ALPN ID used by the connection. If a connection can not be
established, record the time up to the connection failure as
connectEnd
and go to the step labeled final record.secureConnectionStart
attribute as follows:
secureConnectionStart
immediately before the
handshake process to secure the connection.secureConnectionStart
to 0.requestStart
. If a user agent needed
multiple retries to send the request, record the current time
of the last attempt.
Network protocols may not perform the connection establishment, secure connection establishment and request sending in a sequential manner. Therefore, developers should not expect these values to always be in a particular order.
responseStart
immediately after the user agent receives the
first byte of the response.responseEnd
immediately after receiving the last byte of
the response.
transferSize
, encodedBodySize
,
decodedBodySize
to corresponding values, subject to
timing allow check algorithm.responseEnd
is not set, set it to the current time. Record the difference between
responseEnd
and startTime in
duration.redirectStart
and redirectEnd
to 0.
Then, return to the step labeled Fetch start with the redirected
resource.PerformanceResourceTiming
object to 0 except startTime, redirectStart
,
redirectEnd
, and initiatorType
.PerformanceResourceTiming
object.PerformanceResourceTiming
object to the Request's client's global object's
performance
entry buffer.This specification does not specify whether steps
20 and 21 should run before or after the load
event of
the resource—see issue 82 for
related discussion.
Discussion: https://www.w3.org/2016/11/30-webperf-minutes.html
Background: #55. In #79 we added a note to flag the implementation differences across browsers. Ideally, we should aim to converge on a consistent implementation:
The value of the timing attributes MUST monotonically increase to ensure timing attributes are not skewed by adjustments to the system clock while fetching the resource. The difference between any two chronologically recorded timing attributes MUST never be negative. For all resources, including subdocument resources, the user agent MUST record the system clock at the beginning of the root document navigation and define subsequent timing attributes in terms of a monotonic clock measuring time elapsed from the beginning of the navigation.
This section is non-normative.
The PerformanceResourceTiming
interface exposes timing
information for a resource to any web page or worker that has
requested that resource. To limit the access to the
PerformanceResourceTiming
interface, the same origin policy is enforced by default
and certain attributes are set to zero, as described in § 4.5 Cross-origin Resources. Resource providers can
explicitly allow all timing information to be collected for a
resource by adding the Timing-Allow-Origin HTTP response
header, which specifies the domains that are allowed to access the
timing information.
Statistical fingerprinting is a privacy concern where a
malicious web site may determine whether a user has visited a
third-party web site by measuring the timing of cache hits and
misses of resources in the third-party web site. Though the
PerformanceResourceTiming
interface gives timing information
for resources in a document, the cross-origin restrictions prevent
making this privacy concern any worse than it is today using the
load event on resources to measure timing to determine cache hits
and misses.
Thanks to Anne Van Kesteren, Annie Sullivan, Arvind Jain, Boris Zbarsky, Darin Fisher, Jason Weber, Jonas Sicking, James Simonsen, Karen Anderson, Kyle Scholz, Nic Jansma, Philippe Le Hegaret, Sigbjørn Vik, Steve Souders, Todd Reifsteck, Tony Gentilcore and William Chan for their contributions to this work.