Resource Timing API
PerformanceResourceTiming for every subresource: durations, transferSize, initiatorType, and RUM waterfalls.
- browser
- resource-timing
- performance
- network
Resource Timing exposes a PerformanceResourceTiming entry per fetched subresource (scripts, images, CSS, fetch/XHR, etc.). It powers custom waterfalls, CDN debugging, and “which third party ate our LCP budget?” analyses without HAR exports from every user.
Docs: MDN Resource Timing, Resource Timing Level 2.
Read entries
const resources = performance.getEntriesByType('resource');
for (const r of resources) {
console.log({
name: r.name,
initiatorType: r.initiatorType, // script, img, css, fetch, ...
duration: r.duration,
transferSize: r.transferSize,
encodedBodySize: r.encodedBodySize,
decodedBodySize: r.decodedBodySize,
protocol: r.nextHopProtocol,
});
}
Stream with observer:
new PerformanceObserver((list) => {
for (const e of list.getEntries()) sendResource(e);
}).observe({ type: 'resource', buffered: true });
Timing phases (same family as Navigation Timing)
startTime → redirect → worker → dns → connect → request → responseStart → responseEnd
Cross-origin resources without Timing-Allow-Origin hide many detailed timestamps (zeroed) — you still get limited data.
Timing-Allow-Origin: https://app.example.com
CDNs should send TAO if you need real DNS/connect/TTFB splits for cross-origin assets.
Cache inference
| Signal | Interpretation |
|---|---|
transferSize === 0 and decoded > 0 |
Often cache or SW (heuristic) |
encodedBodySize === 0 |
Possible cache/CORS opacity cases |
Large duration, small body |
Latency / queueing |
Treat heuristics carefully under service workers.
Building a mini waterfall
function toRow(r) {
return {
url: r.name,
start: r.startTime,
end: r.responseEnd,
type: r.initiatorType,
size: r.transferSize,
};
}
Sort by startTime to visualize contention. Compare to DevTools Network panel when debugging locally — Network panel.
Privacy
Resource URLs can contain tokens in query strings. Strip sensitive query keys before beacons. Cap the number of resources reported per page.
Soft navigations
SPA route changes don’t clear the resource buffer the way full navigations do. Clear marks/measures thoughtfully and attribute resources to “soft nav IDs” if you build SPA RUM.
Interview out-loud
“Resource Timing gives per-subresource phases, sizes, and initiatorType. Cross-origin detail needs Timing-Allow-Origin. I use it for RUM waterfalls and third-party cost, scrubbing sensitive URLs before send.”
Third-party scoreboard
Aggregate transferSize and duration by host in RUM. Publish a monthly “third-party tax” chart. Teams fight harder for removal when the number is visible in dollars of LCP and lost conversions, not only in a Lighthouse screenshot.
Worker and CORS opacity
Opaque responses from no-cors requests expose limited timing and size data by design. For first-party CDNs you control, send Timing-Allow-Origin matching your app origin so dashboards show real DNS/connect/TTFB splits. Without TAO, your “slow image” investigation is mostly guesswork beyond total duration.
Related
Further depth
Teams often under-invest in this topic until an incident or CWV regression. Schedule a one-hour drill: reproduce the failure mode in DevTools, list the top three mitigations for your stack, and file tickets with owners. Revisit after the next major feature that touches networking, rendering, auth, or third parties — those are the moments regressions land. Keep primary documentation links in the runbook so on-call is not searching chat history at 2am.
Concrete artifacts to leave behind: a short architecture note, a CI assertion or header snapshot, and a dashboard panel (lab or field) that would have caught the last bug. Teaching the rest of the team the mental model matters as much as the one-line fix.
Further reading
Related guides
- Browser DevTools Network PanelRead waterfalls, timing phases, headers, throttling, and initiator chains in the Network panel like a production debugger.
- BFCache Back Forward CacheHow the back/forward cache freezes pages for instant history nav, what blocks it, and how to restore state safely.
- Browser DevTools Performance PanelRecord main-thread timelines: long tasks, style/layout/paint, frames, and how to turn flame charts into INP fixes.
- Browser Networking 101DNS, TCP/TLS, HTTP/1.1 vs H2/H3, connection reuse, and what frontend code can actually influence.
- Compositor LayersWhen browsers promote layers, why transform/opacity animate cheaply, and layer explosion costs.