W3C Candidate Recommendation Draft
Copyright © 2025 World Wide Web Consortium. 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. A list of current W3C publications and the latest revision of this technical report can be found in the W3C standards and drafts index.
This document was published by the Web Performance Working Group as a Candidate Recommendation Draft using the Recommendation track.
Publication as a Candidate Recommendation does not imply endorsement by W3C and its Members. A Candidate Recommendation Draft integrates changes from the previous Candidate Recommendation that the Working Group intends to include in a subsequent Candidate Recommendation Snapshot.
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 a 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 that 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 18 August 2025 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, and SHOULD in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.
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.
      
Throughout this work, all time values are measured in milliseconds since the start of navigation of the document [HR-TIME]. For example, the start of navigation of the document occurs at time 0.
This definition of time is based on the High Resolution Time specification [HR-TIME] 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 fetched http(s)
          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, SVG elements [SVG11]
          such as svg, and
          EventSource.
        
PerformanceResourceTiming Interface
        This section is non-normative.
          Resource Requests fetched by a non-null client
          are included as PerformanceResourceTiming objects in the
          client's global object's
          Performance
          Timeline, unless excluded from the timeline as part of the
          fetching process. Resources that are retrieved from HTTP
          cache are included as PerformanceResourceTiming objects in the
          Performance
          Timeline. Resources for which the fetch was initiated, but
          was later aborted (e.g. due to a network error) are included as
          PerformanceResourceTiming objects in the Performance
          Timeline, with their start and end timing.
        
Examples:
src
          attribute of two HTML IMG elements, the fetch of the
          resource initiated by the first HTML IMG element would
          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. PerformanceResourceTiming entries are only
            reported for http(s) resources.
          PerformanceResourceTiming
          object in the Performance
          Timeline with only the startTime, fetchStart, duration and
          responseEnd set.
          PerformanceResourceTiming object in the
          Performance
          Timeline.
          WebIDL[Exposed=(Window,Worker)]
interface PerformanceResourceTiming : PerformanceEntry {
    readonly attribute DOMString initiatorType;
    readonly attribute DOMString deliveryType;
    readonly attribute ByteString 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 finalResponseHeadersStart;
    readonly attribute DOMHighResTimeStamp firstInterimResponseStart;
    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;
    readonly attribute unsigned short responseStatus;
    readonly attribute RenderBlockingStatusType renderBlockingStatus;
    readonly attribute DOMString contentType;
    readonly attribute DOMString contentEncoding;
    [Default] object toJSON();
};
        
          A PerformanceResourceTiming has an associated DOMString
          initiator
          type.
        
          A PerformanceResourceTiming has an associated DOMString
          delivery
          type.
        
          A PerformanceResourceTiming has an associated DOMString
          requested
          URL.
        
          A PerformanceResourceTiming has an associated DOMString
          cache mode
          (the empty string, "local", or
          "validated").
        
          A PerformanceResourceTiming has an associated fetch timing info timing
          info.
        
          A PerformanceResourceTiming has an associated response body info resource
          info.
        
          A PerformanceResourceTiming has an associated status response status.
        
          A PerformanceResourceTiming has an associated
          RenderBlockingStatusType render-blocking status.
        
          When toJSON is called, run the default toJSON steps
          for PerformanceResourceTiming.
        
          initiatorType getter steps are to return the initiator type for this.
        
            initiatorType returns one of the following values:
          
"navigation", if the request is a navigation request;
            "body", if the request is a result of processing the
              body element's background attribute that's
              already obsolete.
            
                "css", if the request is a result of processing a
                CSS url() directive such as @import
                url() or background: url(); [CSS-VALUES]
              
                Note: the request for a font resource specified with
                @font-face in CSS is a result of processing a CSS
                directive. Therefore, the initiatorType for this font
                resource is "css".
              
"script", if the request is a result of loading any
              script (a classic
              script, a module script, or a Worker).
            "xmlhttprequest", if the request is a result of
              processing an XMLHttpRequest;
            "font", if the request is the result of processing
              fonts. This can happen when fonts request subsequent resources,
              e.g, when Incremental Font Transfer is used.
            "fetch", if the request is the result of processing
              the fetch() method;
            "beacon", if the request is the result of processing
              the sendBeacon() method; [BEACON]
            "video", if the request is the result of processing
              the video element's poster or src.
            "audio", if the request is the result of processing
              the audio element's src.
            "track", if the request is the result of processing
              the track element's src.
            "img", if the request is the result of processing
              the img element's src or srcset.
            "image", if the request is the result of processing
              the image
              element. [SVG2]
            "input", if the request is the result of processing
              an input element of type image.
            "ping", if the request is the result of processing
              an a element's ping.
            "iframe", if the request is the result of processing
              an iframe's src.
            "frame", if the request is the result of loading a
              frame.
            "embed", if the request is the result of processing
              an embed element's src.
            "link", if the request is the result of processing
              an link element.
            "object", if the request is the result of processing
              an object element.
            "early-hints", if the request is the result of
              processing an Early hints response.
            "other", if none of the above conditions match.
            
          The setting of initiatorType is done at the different places where
          a resource timing entry is reported, such as the fetch standard.
        
          deliveryType getter steps are to return the delivery type for this.
        
            deliveryType returns one of the following values:
          
"cache", if the cache mode is not the empty
              string.
            "", if none of the above
            conditions match.
            This is expected to be expanded by future updates to this specification, e.g. to describe consuming preloaded resources and prefetched navigation requests.
          The workerStart getter steps are to convert fetch
          timestamp for this's timing info's final service worker start time and the relevant global
          object for this. See HTTP fetch for more info.
        
          The redirectStart getter steps are to convert fetch
          timestamp for this's timing info's redirect start time and the relevant global object for
          this. See HTTP-redirect fetch for more info.
        
          The redirectEnd getter steps are to convert fetch
          timestamp for this's timing info's redirect end time and the relevant global object for
          this. See HTTP-redirect fetch for more info.
        
          The fetchStart getter steps are to convert fetch
          timestamp for this's timing info's post-redirect start time and the relevant global object
          for this. See HTTP fetch for more info.
        
          The domainLookupStart getter steps are to convert fetch
          timestamp for this's timing info's final connection timing info's domain lookup start time and the relevant global object for
          this. See Recording connection timing
          info for more info.
        
          The domainLookupEnd getter steps are to convert fetch
          timestamp for this's timing info's final connection timing info's domain lookup end time and the relevant global object for
          this. See Recording connection timing
          info for more info.
        
          The connectStart getter steps are to convert fetch
          timestamp for this's timing info's final connection timing info's connection start time and the relevant global object
          for this. See Recording connection timing
          info for more info.
        
          The connectEnd getter steps are to convert fetch
          timestamp for this's timing info's final connection timing info's connection end time and the relevant global object for
          this. See Recording connection timing
          info for more info.
        
          The secureConnectionStart getter steps are to convert
          fetch timestamp for this's timing info's final connection timing info's secure connection start time and the relevant global object for
          this. See Recording connection timing
          info for more info.
        
          The nextHopProtocol getter steps are to isomorphic decode this's timing info's
          final connection timing info's ALPN negotiated protocol. See Recording connection timing
          info for more info.
        
Issue 221 suggests to remove support for nextHopProtocol, as it can reveal details about the user's network configuration.
          The requestStart getter steps are to convert fetch
          timestamp for this's timing info's final network-request start time and the relevant global
          object for this. See HTTP fetch for more info.
        
          The firstInterimResponseStart getter steps are to
          convert fetch timestamp for this's timing info's first interim network-response start time and the relevant
          global object for this. See HTTP fetch for more info.
        
          The finalResponseHeadersStart getter steps are to
          convert fetch timestamp for this's timing info's final network-response start time and the relevant global
          object for this. See HTTP fetch for more info.
        
          The responseStart getter steps are to return this's
          firstInterimResponseStart if it is not
          0; Otherwise this's
          finalResponseHeadersStart.
        
          The responseEnd getter steps are to convert fetch
          timestamp for this's timing info's end time and the relevant global object for this. See
          fetch for more info.
        
          The encodedBodySize getter steps are to return
          this's resource
          info's encoded size.
        
          The decodedBodySize getter steps are to return
          this's resource
          info's decoded size.
        
          The transferSize getter steps are:
        
              If this's cache
              mode is "local", then return 0.
            
              If this's cache
              mode is "validated", then return 300.
            
Return this's response body info's encoded size plus 300.
              The constant number added to transferSize replaces exposing the
              total byte size of the HTTP headers, as that may expose the
              presence of certain cookies. See this
              issue.
            
          The responseStatus getter steps are to return
          this's response
          status.
        
          responseStatus is determined in Fetch. For a cross-origin
          no-cors request it
          would be 0 because the response would be an opaque filtered
          response.
        
          The contentType getter steps are to return this's
          resource info's
          content type.
        
          The contentEncoding getter steps are to return
          this's resource
          info 's content encoding.
        
          The renderBlockingStatus getter steps are to return
          blocking if
          this's timing
          info's render-blocking is true; otherwise
          non-blocking.
        
          A user agent implementing PerformanceResourceTiming would need
          to include "resource" in
          supportedEntryTypes. This allows developers
          to detect support for Resource Timing.
        
WebIDLenum RenderBlockingStatusType {
    "blocking",
    "non-blocking"
};
          The values are defined as follows:
blocking
            non-blocking
            
          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 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.
          WebIDLpartial interface Performance {
          undefined clearResourceTimings ();
          undefined setResourceTimingBufferSize (unsigned long maxSize);
          attribute EventHandler onresourcetimingbufferfull;
        };
        
          The Performance interface is defined in [HR-TIME].
        
          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 new entry into the performance entry buffer, run the following steps:
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).
            
          As detailed in Fetch, requests for cross-origin resources are
          included as PerformanceResourceTiming objects in the
          Performance
          Timeline. If the timing
          allow check algorithm fails for a cross-origin resource, the
          entry will be an opaque entry. Such
          entries have most of their attributes masked in order to prevent
          leaking cross-origin data that isn't otherwise exposed. So, for an
          opaque entry, the following
          attributes will be set to zero:
          redirectStart,
          redirectEnd,
          workerStart,
          domainLookupStart,
          domainLookupEnd,
          connectStart,
          connectEnd,
          requestStart,
          firstInterimResponseStart,
          finalResponseHeadersStart,
          responseStart,
          secureConnectionStart,
          transferSize,
          encodedBodySize, and
          decodedBodySize. Further, the
          nextHopProtocol attribute will be set
          to the empty string.
        
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 those cross-origin restrictions.
The Timing-Allow-Origin HTTP response header field can be used to communicate a policy indicating origin(s) that may be 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, [RFC9110]):
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 user agent MAY still enforce cross-origin restrictions and set transferSize, encodedBodySize, and decodedBodySize attributes to zero, even with Timing-Allow-Origin HTTP response header fields. If it does, it MAY also set deliveryType to "".
The Timing-Allow-Origin headers are processed in FETCH to compute the attributes accordingly.
The Timing-Allow-Origin header may arrive as part of a cached response. In case of cache revalidation, according to RFC 7234, the header's value may come from the revalidation response, or if not present there, from the original cached resource.
This section registers Timing-Allow-Origin as a Provisional Message Header.
Timing-Allow-OriginTiming-Allow-Origin Response Header
            This section is non-normative.
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.
PerformanceResourceTiming interface. Attributes in
            parenthesis indicate that they may not be available if the resource
            fails the timing allow
            check algorithm.
          To mark resource timing given a fetch timing info timingInfo, a DOMString requestedURL, a DOMString initiatorType a global object global, a string cacheMode, a response body info bodyInfo, a status responseStatus, and an optional string deliveryType (by default, the empty string), perform the following steps:
PerformanceResourceTiming object entry in
          global's realm.
          
          To setup the resource timing entry for
          PerformanceResourceTiming entry given DOMString
          initiatorType, DOMString requestedURL, fetch timing info
          timingInfo, a DOMString cacheMode, a response body info
          bodyInfo, a status
          responseStatus, and an optional DOMString deliveryType (by
          default, the empty string), perform the following steps:
        
local", or "validated".
          resource", requestedURL, and the result of
            converting timingInfo's
            end time given global.
          cache".
          
          To convert fetch timestamp given DOMHighResTimeStamp
          ts and global object global, do the following:
        
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 HTTP fetch.
          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.
        
This section is non-normative.
          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
          load event on resources can already measure timing to determine cache
          hits and misses in a limited fashion, and the cross-origin
          restrictions in HTTP Fetch prevent the leakage of any additional
          information.
        
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, William Chan, and Alex Christensen for their contributions to this work.
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: