Happy holiday folks! All the best from us at Digitpaint
🍳

Day 12

Measuring actions with the User Timing API

One thing is for sure; everyone likes a webpage that loads quickly. But what to do when it doesn't? The performance interface can help you by giving access to performance-related information. The performance interface is a collection of different API's. As this is quite a big subject we're going to cover this in the coming days. Today we'll start with the basics: manual marking and measurement of events with the User Timing API.

In the demo below you can add performance marks, which basically creates a labelled timestamp in the browser's performance entry buffer.

Performance API galore

The performance interface is part of the High Resolution Time API, but is enhanced by the User Timing API, the Navigation Timing API and Resource Timing. All of this combined gives us access to client-side latency measurements including calculation of frame-rate (potentially important in animations) and benchmarking (such as resource timings).

The performance interface

Well isn't that a mouthfull? Let's see how we can access this information. It all starts with the performance interface which is accessed through window.performance. The interface exposes the navigation, timing and memory properties.

navigation
Information on how the navigation to the page occurred.
timing
Performance and timing information on the page navigation, including different load/ready/etc. events
memory
A non-standard extension added in Chrome, this poperty provides an object with basic memory usage information.

Marking and measuring

Apart from the read-only properties, the performance interface also has some interesting functions which allow you to dig deeper into what's going on. We're not going to cover the full interface here but will focus on the User Timing API, e.g. the manual creation of marks and measurements.

performance.mark(name)
The mark function adds a named mark to the browser's performance entry buffer. So calling performance.mark("yay") will add an entry labelled "yay".
performance.measure(name, startmark, endmark)

Creates a named entry in the performance entry buffer with the measurement between two marks. Creating measurements works like this:

performance.mark("one");
// ... do stuff ...
performance.mark("two");

performance.measure("one-to-two", "one", "two");
Cleanup
To clean up the marks and entries you can use the performance.clearMarks() and performance.clearMeasures() functions.

Reading entries

We've stored marks and measurements in the performance entry buffer, which is nice, but not very useful in itself. Luckily the performance interface exposes a couple of function that can be used to read the created entries.

performance.getEntries()
Returns an array of all PerformanceEntry objects.
performance.getEntriesByType(type)
Returns an array of PerformanceEntry objects matching type. To get all marks you can call performance.getEntriesByType(mark").
performance.getEntriesByName(name, [type])
Returns an array of PerformanceEntry objects matching name with an optional type. To get all marks named "one" you can call performance.getEntriesByName("one", "mark").

As we can get a bunch of PerformanceEntry objects, let's see what they have to offer data wise. All PerformancEntry objects have at least the following properties:

name
The name of the entry. This is what we passed as name to performance.mark(name) or performance.measuer(name, start, end).
entryType
The type of entry. Will be "mark" for marks and you've probably guessed it "measure" for measures.
startTime
The time the entry "started". For marks and measures this is the time of the call to performance.mark() or performance.measure(). Time is expressed in floating point milliseconds since the current page started to load. To be more exact, it's the number of milliseconds since the performance.timing.navigationStart timestamp.
duration
The duration in milliseconds. For marks this is always 0 as a mark is a single event and has no duration. For measurements it's the difference between the two marks you passed into performance.measure("name", "mark-1", "mark-2").

Now

All performance entries are measured relatively to the moment the page started to load and are expressed in milliseconds (with a precision of 5µs, if your browser/computer can handle it). To relate that to "now", the performance interface exposes performance.now() which will return the current time, also measured relatively to the page load start.

Browser compatibility

Compatibility is really good. The High Resolution Time API and the User Timing API basically work in all modern browsers.

  • Chrome
  • Internet Explorer
  • FireFox
  • Android Chrome
  • Safari
  • Opera

More detailed information on caniuse.com for High Resolution Time API and User Timing API

More information on:

Demo source code

Do you want to see the insides of the demo? Take a look to the JavaScript:

While the core functionality that interacts with the performance interface is in the JavaScript above, we also wrote a bit of code to display the timeline. We're creating the timeline using the D3 library.

Back to home