Spinning a web
window.onload event fired (with non-obvious exceptions based on the fancy of various browser authors).
document.write to modify the contents of the page.
Well, thankfully those days are mostly behind us, and there are ways to deal with bad third parties that still use
This means that users have gotten used to interacting with pages before the spinner stops spinning, and page developers have become smarter about building pages that are usable before they are fully loaded. So for everyone hoping to measure perceived performance, the
window.onload event is no longer the best event to determine when a page is usable.
User Intentions and Journeys
In the past, we’ve looked at various approaches of determining in a generic manner when a particular page is usable, but for a given site, the developer or site owner knows the use cases that the site was designed to handle, and knows which elements are pre-requisites for a particular user to act on their intention.
In order to measure this intent, we need at least two interesting events, one where the user signals their intent to do something, and the second when the page is in a state where they can accomplish their task or their task is complete.
The user may signal intent by entering a URL into the browser, clicking on something, or submitting a form.
An intent to read an article is typically considered complete when the content of that article is visible in the browser, while my intent to submit this article is complete once I hit the Publish button and the browser responds with a success state.
An intent to purchase a gift for someone, on the other hand, may involve a long process with multiple clicks, and submits going through multiple products, reviews, and a checkout process.
Today we’ll look at some simple code to measure when certain things have happened on a page using a
If a user clicks on something, we set a timer, but we also start a
MutationObserver will look for any changes to the DOM starting from the
document object and nesting down into all children and will call the
callback on those changes.
The callback needs to do a few things:
So this is all fairly simple, and it’s well documented. The part we really care about is the “check for interestingness” that I’ve included in comments above.
Check to see if a particular element has loaded
Check to see if an image or script has loaded
MutationObserver does not work well when changing
innerHTML. If you manipulate an element’s
innerHTML, only top level elements in the HTML fire the callback, so we do something else:
Multiple page journeys
Multiple page journeys take this idea a little further. The technical matters of timing the events remains the same. The big difference is that you now need to leverage
cookies to store timer information while you wait for the journey to complete.
There are a large number of documents on working with both, so I won’t go into the code today.
According to CanIUse, MutationObserver is fairly well supported among modern browsers, and there’s a polyfill for older browsers.
I’d especially like to thank Nic for all his work on this project.
Philip Tellis (@bluesmoon) is the Chief Architect of SOASTA where he works on the mPulse product to do Real User Measurement (formerly LogNormal). Philip writes code because it's fun to do. He loves making computers do his work for him and spends a lot of time trying to get the most out of available hardware. He is equally comfortable with the back end and the front end and his tech blog has articles ranging from Operating System level hacks to Accessibility in Rich Internet Applications.
Nic Jansma (@nicj) is a software developer at SOASTA building high-performance websites, apps and open-source tools, and is a Microsoft MVP for IE