HTML5 APIs: Measure Performance with User and Navigation Timing
Complex web applications can slow down the processing power of the client. Hence, it is important – especially for mobile devices – to make some adjustments, so everything runs smoothly. Loading performance can be tested quickly and accurately with the new User Timing API for JavaScript, as the timing data bases on the High-Resolution Time API, which measures timing to the microsecond. The Navigation Timing API determines the loading performance of a website with the help of predefined marks. Thanks to the precise measuring methods, developer’s can find out which part of the application wastes time and optimize it.
Measure Precisely with User Timing API
The User Timing API measures performance between several predefined marks within a web application. You only have to define a start and end mark for the measurement that can be set at any place of the script. The JavaScript object "performance" offers various methods to do that.var measuring_start = performance.now();
With the "now(0)" method, you can start measurement at any place of the web application, for example, within a script that runs a computationally intensive function. In contrast to the "Date(0)" object, which provides system timing as a time stamp, the User Timing API gives you millisecond accuracy with several decimal places. If you, for example, want to analyze the loading performance for an image, you can set the second mark within a "load" event.
document.getElementsByTagName("img")[0].addEventListener("load", function() {
var measuring_end = performance.now();
}, false);
The time elapsed is calculated as the difference between "measuring_start" and "measuring_end".
Set Marks with "mark(0)"
Instead of setting marks with the "now()" method and allocating them a variable, you can use the "mark()" method and give each mark a specific name.performance.mark("start");
…
performance.mark("end");
The "measure()" method then calculates the difference between the two marks. This method needs three values with the first value defining the name for the difference, and the second and third value specifying the names for the marks.
performance.measure("difference", "start", "end");
In this example, the difference between the "start" and "end" mark is calculated. To read out the measuring data use the "getEntriesByType()" method. With this method you can determine the names as well as the measured, or rather calculated, timings for the marks set with "mark()" and "measure()".
var marks = performance.getEntriesByType("mark");
var measuring differences = performance.getEntriesByType("measure");
In this example the names and values readout with "getEntriesByType()" are passed as an array to variables. Then you can pull out all information of the measurements.
console.log(mark[0].name + ": " + mark[0].startTime);
console.log(mark[1].name + ": " + mark[1].startTime);
console.log(measuring differences[0].name + ": " + measuring differences[0].duration);
The "name" feature shows the names of the marks or the calculated difference. Performance between marks set with "mark()" can be displayed with "startTime". Differences calculated with the "measure()" method can be shown with "duration". In the example, everything is written to the browser console.
Instead of addressing the types of the marks and calculations, "getEntriesByName()" allows addressing their names.
var marks = performance.getEntriesByName("start");
console.log(marks[0].name + ": " + marks[0].startTime);
In this example the "start" mark, set with the "mark()" method, is passed to a variable and written into the console.
Remove Marks and Calculations
If you want to delete single marks or calculations or even all, you can do this with the "clearMarks()" and "clearMeasures()" methods. It is possible to pass the names of the deleted values to the methods.performance.clearMarks("start");
In this example, we delete the "start" mark. If you run both methods without passing a name, all predefined marks will be removed.
performance.clearMarks();
Measure Loading Performance of a Website with the Navigation Timing API
In contrast to the User-Timing API, the Navigation Timing API forgoes the precise timing measurement in the microsecond area. Instead, performance is measured with a simple time stamp. The advantage is that the loading performance of a website can be easily determined by predefined marks. You can measure the time needed from "unloading" an open document until a document is loaded. All marks are introduced with "performance.timing" followed by a feature that specifies the measuring time.console.log(performance.timing.navigationStart);
In this example "navigationStart" determines the time when the "unload" event was executed in the document that was previously open. The Navigation Timing API displays the time as a common time stamp in milliseconds. In this example, the time stamp is written into the console.
console.log(performance.timing.domLoading);
console.log(performance.timing.domComplete);
In the second example, the time is measured when the browser starts loading the DOM tree. It then determines the time when the DOM tree is fully loaded.
If you rather want to know the duration of the loading times, you will need to determine the current time stamp first. You can then subtract all values determined by "performance.timing" from the time stamp.
window.addEventListener("load", function() {
var now = new Date().getTime();
console.log(now - performance.timing.domComplete);
}, false);
In this example, only the time difference until the DOM tree is fully loaded is written into the console. There are 21 different features that measure the time up to a certain point within a loading process.
Besides "timing" there is also the "navigation" object that has two features. The feature "type" gives detail in the form of a number about how the document was opened.
console.log(performance.navigation.type);
If the number is 0, the document was opened by a link or direct input. If the number is two the document was opened by the navigation buttons of the browser. If none of the options fits, the value 255 will be returned.
If the site was opened by redirection, "redirectCount" shows the number of redirections until the current document was loaded.
console.log(performance.navigation.redirectCount);
Browser Support
The User Timing API works in all standard browsers, including Internet Explorer 10+. Older browser versions can be used with a polyfill that requires the support of the High-Resolution Time API. You will need at least Chrome version 20, Firefox version 15, or Internet Explorer version 10. Older versions of the named browsers already support the Navigation Timing API. So, they can be used with Chrome and Firefox without problems. Internet Explorer supports it from version 9.Related Links
- User Timing Polyfill
- Navigation Timing Test