Happy holiday folks! All the best from us at Digitpaint

Day 13

Timing navigation and page load with the Navigation Timing API

Yesterday we described the performance interface but we just skimmed over the different properties it has. Today we're going to fix that and dive deeper into navigation and timing and we'll take a short look at the PerformanceNavigationTiming entry.

In the demo below we've plotted the loading of the page you're on up until the loadEvent.


The timing property returns a PerformanceTiming object containing performance timings. This is the information we use to display the diagram in the demo. MDN has an excellent overview of the meaning of all it's properties.

The timings in the PerformanceTiming object are unix timestamps in milliseconds. It's important to note that this is different from the timings in the performance entry buffer. If the value is zero, it means that an event did nog occur.

Evaluating timing data

The timing data becomes even more useful when we combine these properties to pinpoint problems. Some examples:

  • Network latency: responseEnd - fetchStart
  • The time taken for page load once the page is received from the server: loadEventEnd - responseEnd
  • The whole process from navigation to page load: loadEventEnd - navigationStart

Keep in mind that when you're getting timing data in one of the events that are also included in the timing data (onload and domcontentloaded) all timing data that will occur after these events will be 0 when read.


The PerformanceNavigation object, which is accessed through performance.navigation gives use context about the performed operations included in the times listed in timing. It will for example tell us whether the page was a load or a refresh or how many times the user has been redirected. Again the MDN documentation covers the nitty gritty fairly well.

Performance entries

Instead of using the direct interfaces we can also get a PerformanceNavigationTiming entry from the performance entry buffer. We can get the entries by using performance.getEntriesByType("navigation"). This PerformanceEntry object contains the same timing information as the timing interface, but using the PerformanceNavigationTiming object has a few advantages.

  • It has a higher precision timer as it uses the High Resolution Timer API
  • It's timings are based on the start of the navigation instead of unix timestamps, which makes it easier to work with them.
  • It also contains the info from performance.navigation in a bit more readable manner.
  • It also contains size information like transferSize, encodedBodySize and decodedBodySize

Browser compatibility

Browser compatiblity is quite excellent: all recent versions of major browser support the described interfaces. There is one caveat, not all browsers support the toJSON() method.

  • chrome
  • edge
  • ie
  • firefox
  • android chrome
  • safari
  • ios safari

More detailed information on caniuse.com for Navigation Timing API.

More about this

Demo source code

What to see how the demo is done? Have a look to the JS file of the demo:

While the core functionality that interacts with the performance interface is in the JavaScript above, we use the same CSS/JS to draw the timeline as yesterday.

Back to home