Measuring Navigation Time with the JavaScript Navigation API

John Au-Yeung - Jan 22 '21 - - Dev Community

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

Subscribe to my email list now at http://jauyeung.net/subscribe/

To measure navigation events like page load and going to different pages, we can use the Navigation Timing API.

In this article, we’ll take a look at how to use it in various scenarios.

Navigation Timing API

We can use the Navigation Timing API to collect performance data on the client which can then be transmitted to a server. The API also lets us measure data that was previously difficult to obtain, like the amount of time needed to unload the previous page, the time it takes to look up domains, total time pent running window’s load handler, etc.

All timestamps returned are measured in milliseconds. All properties are read-only.

The main interface for measure navigation performance is the PerformanceNavigationTiming interface.

A simple example to measure page load time would be the following:

const perfEntries = performance.getEntriesByType("navigation");
const [p] = perfEntries;
const pageLoadTime = `p.loadEventEnd - p.loadEventStart;`
console.log(pageLoadTime)
Enter fullscreen mode Exit fullscreen mode

The code above measures the time between the loadEventStart event and loadEventEnd event is triggered.

We can also use it to measure how long it takes the DOM of a document to load as follows:

const perfEntries = performance.getEntriesByType("navigation");
const [p] = perfEntries;
const domLoadTime = p.domContentLoadedEventEnd - p.domContentLoadedEventStart;
console.log(domLoadTime)
Enter fullscreen mode Exit fullscreen mode

In the code above, we used the domContentLoadedEventEnd and domContentLoadedEventStart properties to get the timing of the when the DOM finished loading and when the DOM started loading with those 2 properties respectively.

We can also use the domComplete to get when the DOM finished loading and when the page is interaction with the interactive properties of a performance entry.

We can write the following:

const perfEntries = performance.getEntriesByType("navigation");
const [p] = perfEntries;
console.log(p.domComplete);
Enter fullscreen mode Exit fullscreen mode

Likewise, we can do something similar to measuring unloading time:

const perfEntries = performance.getEntriesByType("navigation");
const [p] = perfEntries;
const domLoadTime = p.unloadEventEnd - p.unloadEventStart;
console.log(domLoadTime)
Enter fullscreen mode Exit fullscreen mode

Other Properties

We can get the number of redirects since the last non-redirect navigation under the current browsing context with the redirectCount read-only property.

To use it, we can write the following:

const perfEntries = performance.getEntriesByType("navigation");
const [p] = perfEntries;
console.log(p.redirectCount);
Enter fullscreen mode Exit fullscreen mode

The type property will get us the navigation type. The possible values of this property are 'navigate', 'reload', 'back_forward', or 'prerender'.

We can get the type as follows:

const perfEntries = performance.getEntriesByType("navigation");
const [p] = perfEntries;
console.log(p.type);
Enter fullscreen mode Exit fullscreen mode

Methods

We can serialize a PerformanceNavigationTiming object with the toJSON method.

To use it, we can write:

const perfEntries = performance.getEntriesByType("navigation");
const [p] = perfEntries;
console.log(p.toJSON());
Enter fullscreen mode Exit fullscreen mode

Then we get something like the following from the console.log:

{
  "name": "https://fiddle.jshell.net/_display/",
  "entryType": "navigation",
  "startTime": 0,
  "duration": 0,
  "initiatorType": "navigation",
  "nextHopProtocol": "h2",
  "workerStart": 0,
  "redirectStart": 0,
  "redirectEnd": 0,
  "fetchStart": 0.31999999191612005,
  "domainLookupStart": 0.31999999191612005,
  "domainLookupEnd": 0.31999999191612005,
  "connectStart": 0.31999999191612005,
  "connectEnd": 0.31999999191612005,
  "secureConnectionStart": 0.31999999191612005,
  "requestStart": 2.195000008214265,
  "responseStart": 89.26000000792556,
  "responseEnd": 90.5849999981001,
  "transferSize": 1435,
  "encodedBodySize": 693,
  "decodedBodySize": 1356,
  "serverTiming": [],
  "unloadEventStart": 95.75999999651685,
  "unloadEventEnd": 95.75999999651685,
  "domInteractive": 116.96000001393259,
  "domContentLoadedEventStart": 116.97000000276603,
  "domContentLoadedEventEnd": 117.20500001683831,
  "domComplete": 118.64500000956468,
  "loadEventStart": 118.68000001413748,
  "loadEventEnd": 0,
  "type": "navigate",
  "redirectCount": 0
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

The PerformanceNavigationTiming interface is very handy for measure page navigation and loading times.

It’s information that’s hard to get any other way.

The interface provides us with various read-only properties that give us the timing of when various page load and navigation-related events occurred. All times are measured in milliseconds.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .