PerformanceNavigationTiming

PerformanceNavigationTiming provides detailed timing data for the current document navigation, including network phases, DOM milestones, redirects, navigation type, and transfer sizes. Frontend engineers can use it to diagnose where page-load time is being spent and to collect real-user performance measurements.

PerformanceNavigationTiming is a Performance API interface representing navigation-related timing for the current document. It is a `PerformanceEntry` with `entryType` equal to `"navigation"`, and it also inherits resource-timing information. The current document normally has one navigation entry in the performance timeline.

The entry exposes timestamps covering stages such as DNS lookup, connection setup, request transmission, first response byte, response completion, DOM parsing, `DOMContentLoaded`, and the load event. These timestamps are high-resolution values relative to the navigation timing origin, so differences between timestamps can be used to calculate phase durations. For example, `responseStart - requestStart` approximates the time from sending the document request until the first response byte arrives.

Useful navigation-specific properties include `type`, which identifies `"navigate"`, `"reload"`, or `"back_forward"`, and `redirectCount`, which reports redirects since the last non-redirect navigation. The interface also exposes size and protocol information inherited from `PerformanceResourceTiming`, such as `transferSize`, `encodedBodySize`, `decodedBodySize`, and `nextHopProtocol`.

The usual access pattern is `performance.getEntriesByType("navigation")`. A `PerformanceObserver` can instead observe `navigation` entries, with `buffered: true` allowing an observer created after navigation to receive entries already recorded. This is useful for instrumentation code that needs to run after the initial navigation has progressed.

Timing data has security and privacy constraints. In particular, some inherited resource-timing values can be unavailable for cross-origin resources unless the relevant response supplies `Timing-Allow-Origin`; therefore, a zero value does not necessarily mean that a network phase literally took zero milliseconds. The older `PerformanceTiming` and `PerformanceNavigation` interfaces are retained for compatibility, while new code should use `PerformanceNavigationTiming`.

Key points

Interview questions

How do you retrieve the navigation timing information for the current page?

Use `performance.getEntriesByType("navigation")` and inspect the resulting `PerformanceNavigationTiming` entry. The current document normally contributes one navigation entry. You can then read properties such as `responseStart`, `domContentLoadedEventEnd`, `loadEventEnd`, `type`, and `redirectCount`. For instrumentation that observes entries asynchronously, `PerformanceObserver` can observe entries of type `navigation`.

How would you calculate the time spent waiting for the first response byte?

Use `responseStart - requestStart` on the navigation entry. `requestStart` marks the point at which the browser begins the document request, while `responseStart` marks receipt of the first response byte. The result can help identify server or network latency, although interpretation should account for caching, connection reuse, and browser timing restrictions. It is one component of overall navigation performance rather than a complete measure of user-perceived speed.

What is the difference between `type` values `navigate`, `reload`, and `back_forward`?

`navigate` covers ordinary navigation such as following a link, entering a URL, or submitting a form. `reload` indicates a browser reload or equivalent reload operation. `back_forward` represents traversal through the browser's session history. These categories are useful when segmenting performance data because different navigation mechanisms can have different loading behavior.

Why might a navigation timing property be zero even though the operation happened?

A zero value can result from browser security restrictions, especially for cross-origin timing information without the appropriate `Timing-Allow-Origin` response header. Caching and other special cases can also affect what timing information is exposed. Therefore, instrumentation should interpret zero according to the property's semantics rather than automatically treating it as a measured zero-duration operation. For cross-origin resources, the server must explicitly permit timing exposure when detailed resource timing is required.

How would you instrument navigation performance in a production frontend?

I would read the navigation entry and derive a small set of meaningful phase durations rather than sending every raw field by default. I would segment results by factors such as navigation type, browser, connection characteristics, and application version, while respecting privacy and data-volume constraints. I would use `PerformanceObserver` where asynchronous observation fits the application's lifecycle, and send aggregated or sampled measurements to the monitoring backend. I would also combine navigation timing with user-centric metrics such as LCP and INP because navigation milestones alone do not fully describe perceived performance.