PerformanceResourceTiming

PerformanceResourceTiming provides detailed timing and transfer information for individual resources fetched by a web page. Frontend engineers use it to diagnose network latency, identify slow resources, and understand where resource loading time is spent.

PerformanceResourceTiming entries are produced by the Resource Timing API and describe resources such as scripts, stylesheets, images, fonts, and fetch/XHR requests. Each entry extends PerformanceEntry and exposes timestamps for stages of the resource-fetch process, with times expressed relative to the document's performance timeline.

Important timestamps include `fetchStart`, `domainLookupStart`, `domainLookupEnd`, `connectStart`, `connectEnd`, `requestStart`, `responseStart`, and `responseEnd`. These let you break resource latency into phases such as DNS lookup, connection establishment, request-to-response delay, and response transfer. `duration` represents the interval from `startTime` to `responseEnd`.

The interface also exposes transfer and encoding information. `transferSize` describes bytes transferred for the resource, including relevant HTTP overhead, while `encodedBodySize` and `decodedBodySize` describe the encoded and decoded response body sizes. Comparing these values can help identify compression effectiveness and caching behavior, although interpretation depends on how the resource was fetched.

`nextHopProtocol` identifies the network protocol used for the resource, such as HTTP/1.1, HTTP/2, or HTTP/3 when reported by the browser. Other properties provide information about redirects, workers, TLS connection setup, and response status. Cross-origin resources can have restricted timing details unless the server supplies an appropriate `Timing-Allow-Origin` response header.

Entries are accessed through `performance.getEntriesByType('resource')`, `performance.getEntriesByName()`, or a `PerformanceObserver`. A `PerformanceObserver` is generally preferable when an application needs to monitor resources as they are added rather than inspecting only entries already available at the time of the query.

Key points

Interview questions

What is PerformanceResourceTiming used for?

It provides detailed performance information for individual resources loaded by a page. A developer can inspect entries for scripts, images, stylesheets, and other fetched resources. The timing fields help identify whether time was spent in DNS, connection setup, waiting for the response, or transferring the response. This makes it useful for diagnosing slow network resources.

How would you identify where a resource's latency comes from?

I would inspect the timestamps for the resource and compare the intervals between them. For example, `domainLookupEnd - domainLookupStart` estimates DNS lookup time, while `connectEnd - connectStart` covers connection establishment. The interval from `requestStart` to `responseStart` indicates time waiting for the initial response, and `responseEnd - responseStart` reflects response transfer time. I would compare these measurements across resources rather than interpreting a single timestamp in isolation.

What is the difference between transferSize, encodedBodySize, and decodedBodySize?

`encodedBodySize` represents the response body size after content encoding but before transfer. `decodedBodySize` represents the body size after decoding. `transferSize` represents bytes transferred for the resource and can include HTTP-related overhead, so it is not simply the same as either body-size field. These values can help analyze compression and caching, but their interpretation should account for browser and protocol behavior.

Why might cross-origin resource timing information be unavailable or restricted?

Browsers apply cross-origin protections to detailed resource timing information. A cross-origin resource generally needs the server to explicitly permit timing information through the `Timing-Allow-Origin` response header. Without the appropriate permission, some detailed timing and size information may be unavailable or restricted. This prevents a page from freely learning sensitive network characteristics about resources on other origins.

When would you use PerformanceObserver instead of directly querying resource entries?

I would query `performance.getEntriesByType('resource')` when I need a snapshot of resource entries that are already available. I would use `PerformanceObserver` when I need to react to resource entries as they are recorded, especially for resources that load after the initial inspection. An observer can also make continuous collection more natural for real-user monitoring. The choice depends on whether the requirement is point-in-time analysis or ongoing observation.