Measuring Web Page Performance

We’re focused on making Internet Explorer 9 amazingly fast, and we want to help web developers make their sites fast as well. Enabling developers to accurately measure the performance of their websites is critical to making the web faster and enabling a new class of HTML5 applications. At Velocity, we announced Internet Explorer 9 as the first browser to provide performance information to developers at runtime, which we introduced in the latest IE9 platform preview. With special thanks to Steve Souders and Zhiheng Wang from Google, the WebKit team and Mozilla.

Measuring real-world performance of websites is difficult and error prone today. Developers are forced to use hacks, such as injecting low resolution JavaScript timestamps throughout their code, which slows down the pages for end users, introduces an observer effect, and provides inaccurate results which can drive the wrong behavior.

The browser knows exactly how long it takes to load and execute a webpage, so we believe the right solution is for the browser to provide developers an API to access these performance results. Web developers shouldn’t have to think about how to measure performance – it should just be available for them.

It’s important for this API to be interoperable across all browsers and platforms so that developers can consistently rely on these results. The Web Timing specification at the W3C is a good foundation for solving this problem in an interoperable manner. The implementation that you’ll find in the latest IE9 platform preview is based off the navigation section of Web Timings and we’ve started conversations with the W3C and other browser manufacturers about working together to get Web Timing chartered and broadly supported.

Let’s take a closer look at how developers are forced to measure performance today and what the new API’s enable.

How Developers Measure Performance Today

Today, in order to collect performance metrics a web developer has to instrument their code with specific timing markers at strategic places on their web page. This can result in code that opposes performance best practices. Developers write something like this:

 <html>
    <head>
        <script type=”text/javascript”>
        var start = (new Date).getTime();
        </script>
    </head>
    <body>
        <script type=”text/javascript”>
        /* do work here */
        var pageLoad = (new Date).getTime() - start; 
        </script>
    </body>
</html>

This approach has several problems. It forces the JavaScript engine to load earlier than normal. It forces the HTML and JavaScript parsers to switch contexts. It may block parallel requests to load the remaining resources.

Something else to mention is that this JavaScript approach does not capture network latency timings, which is the time associated from when the document is initially requested from the server to the time it arrives and is displayed to the end-user.

Additionally, while the Date function is available across all browsers, the results vary in precision. John Resig has a nice blog post in which he goes to some lengths to determine that the time from (new Date).getTime(); is as precise as 7.5ms on average across browsers, half the interval for the Windows system timer at 15ms. Many operations can execute in under 1ms which means that some measurements can have an error range of 750%!

How Developers can Measure Performance with Internet Explorer 9

The third Internet Explorer 9 platform preview contains a prototype implementation of the Web Timings NavigationTiming interface called window.msPerformance.timing. Following convention, we use a vendor prefix (ms) on the namespace because the spec is under development. There are no other implementations yet, and therefore no interoperability with other browsers. This interface captures key timing information about the load of the root document with sub-millisecond accuracy, which is immediately available from the DOM once the page had loaded.

window.msPerformance.timing

 interface MSPerformanceTiming{
     readonly attribute unsigned longlong navigationStart;
     readonly attribute unsigned longlong fetchStart;
     readonly attribute unsigned longlong unloadStart;
     readonly attribute unsigned longlong unloadEnd;
     readonly attribute unsigned longlong domainLookupStart;
     readonly attribute unsigned longlong domainLookupEnd;
     readonly attribute unsigned longlong connectStart;
     readonly attribute unsigned longlong connectEnd;
     readonly attribute unsigned longlong requestStart;
     readonly attribute unsigned longlong requestEnd;
     readonly attribute unsigned longlong responseStart;
     readonly attribute unsigned longlong responseEnd;
     readonly attribute unsigned longlong domLoading;
     readonly attribute unsigned longlong domInteractive;
     readonly attribute unsigned longlong domContentLoaded;
     readonly attribute unsigned longlong domComplete;
     readonly attribute unsigned longlong loadStart;
     readonly attribute unsigned longlong loadEnd;
     readonly attribute unsigned longlong firstPaint;
     readonly attribute unsigned longlong fullyLoaded;
}

For the first time, web developers can accurately understand how long it takes to load their page on their customer’s machines. They have access to when the end-user starts navigation (navigationStart), the network latency related to loading the page (responseEnd - fetchStart), and the elapsed time to load the page within the browser.

Developers can use this information to adapt their applications at runtime for maximum performance, and they can use their favorite serialization interface to package these timings and store them on the server to establish performance trends.

With JSON, this would look something like this:

JSON.Stringify(window.msPerformance);

Another useful feature of window.msPerformance is the ability to only query for the elapsed time taken in important time phases of loading the document called timingMeasures.

window.msPerformance.timingMeasures

 interface MSPerformanceTimingMeasures{
     readonly attribute unsigned longlong navigation;
     readonly attribute unsigned longlong fetch;
     readonly attribute unsigned longlong unload;
     readonly attribute unsigned longlong domainLookup;
     readonly attribute unsigned longlong connect;
     readonly attribute unsigned longlong request;
     readonly attribute unsigned longlong response;
     readonly attribute unsigned longlong domLoading;
     readonly attribute unsigned longlong domInteractive;
     readonly attribute unsigned longlong domContentLoaded;
     readonly attribute unsigned longlong domComplete;
     readonly attribute unsigned longlong load;
     readonly attribute unsigned longlong firstPaint;
     readonly attribute unsigned longlong fullyLoaded;
}

Simply access window.msPerformance.timingMeasures.navigation after the page has been loaded and you have the time taken to perform the navigation to the loaded document.

Finally, the window.msPerformance.navigation interface contains information such as the type of navigation and additional network activity that occurred on the page to help describe the overall navigation experience.

window.msPerformance.navigation

 interface MSPerformanceNavigation{
     const unsigned short NAVIGATION = 0;
     const unsigned short RELOAD_BACK_FORWARD = 1;

     readonly attribute unsigned longlong type;
     readonly attribute unsigned longlong redirectedCount;
     readonly attribute unsigned longlong uniqueDomains;
     readonly attribute unsigned longlong requestCount;
     readonly attribute unsigned longlong startTime;
}

Let’s look at it in action

On the IE9 Test Drive site, you can try the window.msPerformance Test Drive demo. There you see a visualization of the time to load the demo page as shown below.

See

In this example, the overall navigation took 111ms to go from when the link is clicked to the time the contents are loaded within the platform preview.

Check it out!

Everything described here is available now in the third platform preview. Check it out at https://ietestdrive.com and try out the window.msPerformance Test Drive demo. This interface is a prototype of a working draft. The API may change, but we want to release this early so that developers can begin to use the API and provide feedback. Please give window.msPerformance interface a try and let us know what you think by providing feedback through the Connect.

Anderson Quach
Program Manager

Edit 6/29 - correction in sentence describing demo page load time.  Overall navigation took 111ms, not 72ms.