This specification defines an interface for web applications to access the complete timing information for resources in a document.
Implementers are encouraged to look at the latest version of Resource Timing before implementing this Candidate Recommendation.
This specification uses DOMHighResTimeStamp and time origin from High Resolution Time Level 2 [[HR-TIME-2]]. These were also defined in High Resolution Time Level 1 but Level 2 provides more refined definitions.
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 qresource 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>
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 IDL fragments in this specification must be interpreted as required for conforming IDL fragments, as described in the Web IDL specification. [[!WebIDL]]
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. [[DOM]]
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. [[ECMA-262]]
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 [[XMLHttpRequest], HTML elements [[HTML51]] 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]], where time is measured in milliseconds since midnight of January 1, 1970 (UTC).
The PerformanceResourceTiming interface facilitates timing measurement of downloadable resources. For example, this interface is available for XMLHttpRequest objects [[XHR]], HTML elements [[HTML51]] such as iframe, img, script, object, embed, and link with the link type of stylesheet, and SVG elements [[SVG11]] such as svg.
All resources fetched by the current browsing [[!HTML51]] or worker [[!WORKERS]] context's MUST be included as PerformanceResourceTiming objects in the Performance Timeline of the relevant context, without violating the origin policy. Resources that are retrieved from relevant application caches or local resources MUST be included as PerformanceResourceTiming objects in the Performance Timeline [[!PERFORMANCE-TIMELINE-2]].
Aborted requests or requests that don't return a response MAY be included as PerformanceResourceTiming objects in the Performance Timeline of the relevant context.
Future versions of this specification could require the inclusion of aborted requests or requests that don't return a response (see issue 12).
Implementers should be aware of Issue 27: Same-origin policy & observing no-cors fetches.
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
InterfaceThe PerformanceResourceTiming interface participates in the Performance Timeline and extends the following attributes of the PerformanceEntry interface:
name
entryType
entryType
attribute MUST return the DOMString "resource
".startTime
startTime
attribute MUST return a DOMHighResTimeStamp [[!HR-TIME-2]]
with the time immediately before the user agent starts to queue the resource for fetching.
If there are HTTP redirects or equivalent
when fetching the resource, and if all the redirects or equivalent are from the same origin as the current
document or the timing allow check algorithm passes, this attribute MUST return the same value as redirectStart.
Otherwise, this attribute MUST return the same value as fetchStart.duration
duration
attribute MUST return a DOMHighResTimeStamp
equal to the difference between responseEnd and startTime, respectively.[Exposed=(Window)] interface PerformanceResourceTiming : PerformanceEntry { readonly attribute DOMString initiatorType; 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; serializer = {inherit, attribute}; };
On getting, the initiatorType attribute MUST return one of the following DOMString
:
localName
of that
element
[[!DOM]], if the initiator is an element
."css"
, if the initiator is a CSS resource downloaded by the url()
syntax [[!CSS-SYNTAX-3]], such as @import url()
or background: url()
."xmlhttprequest"
, if the initiator is an XMLHttpRequest object [[!XHR]].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:
On getting, the domainLookupEnd attribute MUST return as follows:
On getting, the connectStart attribute MUST return as follows:
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:
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.
The secureConnectionStart attribute is optional. On getting, the attribute MUST return as follows:
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:
Performance
Interface
The 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 150, 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:
This buffer is the same one as the performance entry buffer defined in [[PERFORMANCE-TIMELINE-2]].
partial interface Performance { void clearResourceTimings (); void setResourceTimingBufferSize (unsigned long maxSize); attribute EventHandler onresourcetimingbufferfull; };
The Performance
object
is defined in [[!HR-TIME-2]].
The method clearResourceTimings runs the following steps:
The setResourceTimingBufferSize method runs the following steps:
The attribute onresourcetimingbufferfull is the event handler for the resourcetimingbufferfull
event.
To add a PerformanceResourceTiming entry (new entry) in the performance entry buffer, run the following steps:
bubbles
attribute initialized to true, and has no default action.Cross-origin resources MUST be included as PerformanceResourceTiming objects in the Performance Timeline. If the timing allow check algorithm fails for a cross-origin resource, these attributes of its PerformanceResourceTiming object MUST be set to zero: redirectStart, redirectEnd, domainLookupStart, domainLookupEnd, connectStart, connectEnd, requestStart, responseStart, and secureConnectionStart.
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]]:
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 is same origin, return pass
.
If the Timing-Allow-Origin header value list contains a
case-sensitive match for the value of the
origin
of the current document, or a wildcard ("*
"),
return pass
.
fail
.
The following graph illustrates the timing attributes defined by the PerformanceResourceTiming interface. Attributes underlined may not be available when fetching resources from different origins. User agents may perform internal processing in between timings, which allow for non-normative intervals between timings.
For each resource included in the performance timelime, perform the following steps:
resource
.
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.
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 . 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.
We would like to sincerely thank Karen Anderson, Darin Fisher, Tony Gentilcore, Nic Jansma, Kyle Scholz, Jonas Sicking, James Simonsen, Steve Souders, Annie Sullivan, Sigbjørn Vik, Jason Weber to acknowledge their contributions to this work.