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 callingperformance.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()
andperformance.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 callperformance.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 callperformance.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)
orperformance.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()
orperformance.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 theperformance.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.