Measuring Mobile Site Performance Using the W3C Navigation Timing API

As web sites become more like applications, measuring and tuning their performance dramatically increases in importance, especially on mobile devices where latency and other performance-related factors have a high impact on user satisfaction. In fact, GigaOM just recently released findings that almost half of users are much less likely to return to a Web site that loads slowly on their handset.

We consider helping developers to measure real-world performance of their mobile sites to be so important that we were on the leading edge of implementing the W3C Navigation Timing interface in Internet Explorer 9, and helped drive it to Candidate Recommendation status very quickly. This interface is available via the window.performance object on IE9 for Windows Phone “Mango” devices, and you can read more about the work we’ve done on this standard here and here. If you don’t have a Mango device, you can download the easy-to-use emulator from the App Hub on MSDN.

What Navigation Timing Measures

The Navigation Timing interface gives Web developers a way of measuring a complete end-to-end picture of user latency – that is, the total amount of time involved in various parts of the process by which a user first requests a Web resource until the time point where it has finished loading in the browser.

This is an important distinction from purely JavaScript-based measures that may be able to (roughly) measure, say, the time it takes to load a page, but cannot get access to more detailed information such as redirect timing or domain lookup latency.

Using the Navigation Timing features, you can measure things such as (but not limited to):

  • Time needed to unload previous page
  • Time elapsed to look up a page’s domain
  • The time points at which the page DOM starts to load and then becomes interactive
  • Time required to perform the window.onload event
  • Total time required to load a page from initial navigation request

Using the Navigation Timing API

The Navigation Timing features are available from the window.performance object (as with any feature, your code should make sure that the given feature actually exists before attempting to use it), which itself just provides objects for timing and navigation. Assuming the feature is supported, you can use the window.performance.timing and window.performance.navigation objects to obtain timing data.

Navigation Information

The PerformanceNavigation Interface defines two properties and a few constants:

Property

Description

type

The type of navigation. Can be TYPE_NAVIGATE (0), TYPE_RELOAD (1), TYPE_BACK_FORWARD (2), or TYPE_UNDEFINED (255).

redirectCount

Indicates the number of redirects the navigation experienced for the page to load in the browser

The type field indicates what kind of navigation was measured. This can be either a normal navigation, a reload event, or a programmatic navigation event via the history object. NOTE: Navigations that result from client-side redirects such as using a <meta> tag with a refresh directive are not counted as redirects – the API reports these as whether they caused a reload or a navigation to a new URL.

Timing Information

The actual timing information for the navigation is available on the timing object, which implements the PerformanceTiming interface. Each of these properties represents a time point during the lifecycle of the navigation event. These time points, listed in order of their occurrence, are:

Timing Field

Description

navigationStart

Time point at which the navigation begins

unloadEventStart

Time at which the user agent starts unloading the previous document, if there is one, otherwise 0

unloadEventEnd

Time at which the previous document finishes unloading the previous document, otherwise 0

redirectStart

If any redirects are involved, this is the time point at which the first fetch request that initiates the redirect starts, other wise 0

redirectEnd

If there were any redirects involved, the time point at which the last byte of the last redirect is received, otherwise 0

fetchStart

For HTTP GET requests, the time at which the user agent starts to check the application cache, otherwise the point at which the resource fetch starts

domainLookupStart

Time point at which the user agent starts the domain name lookup for the document. If the document is retrieved from the cache, this is the same as fetchStart

domainLookupEnd

Time at which the user agent finishes looking up the domain name. If the document is being retrieved from a cache or locally, same as fetchStart

connectStart

Time when the user agent starts establishing a connection to the server. If the document is retrieved from the application cache or otherwise locally, this is the same as domainLookupEnd

connectEnd

Time when the user agent finishes establishing a connection to the server. If the document is retrieved from the application cache or otherwise locally, this is the same as domainLookupEnd

secureConnectionStart

Optional attribute – it is undefined for user agents that don’t provide it. If HTTPS is used, this is the time point when the user agent starts the handshake process to secure the connection. If HTTPS is not used, this is 0

requestStart

The time when the user agent starts requesting the document from the server, or from the application cache or other local resource

responseStart

Time point immediately following when the user agent receives the first byte of the response from the server, application cache, or local resource

responseEnd

Time point immediately following when the user agent receives the last byte of the response from the server, application cache, or local resource

domLoading

Time point when the user agent sets the readyState of the current document to “loading”

domInteractive

Time point when the user agent sets the readyState of the current document to “interactive” – this is the first point where the user can interact with the page

domContentLoadedStart

Time point right before the user agent fires the DOMContentLoaded event

domContentLoadedEnd

Time point right after the DOMContentLoaded event completes

domComplete

Time point right before the user agent sets the readyState to “complete”

loadEventStart

Time point right before the user agent fires the onload event

loadEventEnd

Time point right after the onload event completes

To calculate the amount of time required for a particular navigation sequence, you can simply subtract one value from another. For example, to calculate the total time required to load a page, you can simply subtract navigationStart from loadEventEnd:

var perfData = window.performance.timing;
var pageLoadTime = perfData.loadEventEnd – perfData.navigationStart;

Or, if you wanted to see how long the request-response process took, you could simply use:

var connectTime = perfData.responseEnd – perfData.requestStart;

The Timing Sequence of Events

Each of the timing events fires at a defined point in the page navigation process, illustrated by the following figure:

NavigationTiming

Practical Usage

Having this data available inside your page can provide several real-world benefits. Site developers, for example, can implement a URL parameter switch that turns on performance testing for the page, allowing testers to gather data from live production pages. Or, a site might choose to implement an “opt-in” feature for live users to provide this performance feedback via XHR so that the site can measure how well pages are being navigated to in the wild.

Microsoft is committed to working with the W3C to create an interoperable way of measuring the performance of Web sites, of which the Navigation Timing API is just a start. Let us know how you’re using the API and what kinds of insights it has helped you find!

Happy Coding!

Joe Marini (@joemarini)
Principal Program Manager, Internet Explorer Windows Phone