All Docs

So how does this thing work?

1. Roundtrip measurements

We define round trip time as the time taken from the user initiating a resource request to when that resource is completely available for the user to interact with. We limit our measurements only to HTML page type resources.

The round trip time is therefore the time from the user clicking on a link to the page referenced by that link becoming usable by the user. For most cases, this is as good as measuring the time from the previous page's onbeforeunload event firing to the current page's onload event firing. In some cases this may be different, but we let the developer determine those events.

This is how we measure.

  1. attach a function to the window.onbeforeunload, document.onmouseup (only activated for links) and form.onsubmit (for all forms on the page) events.

    Inside the last invocation of this function, we take a time reading (in milliseconds) and store it into a session cookie along with the URL of the current page or the URL of any clicked link or submitted form.

  2. attach a function to the window.onunload (non-Safari) and window.onpagehide (Safari) events.

    We take a time reading in this function as well, and store it in the session cookie.

  3. attach a function to the window.onload event.

    Inside this function, we take a time reading (in milliseconds) and call this rt.end.

    If the browser has implemented the WebTiming API, we pull out navigationStart (or fetchStart if navigationStart is unset). To get around a bug in Firefox 7 and 8, we use unloadEventStart instead.

    If the WebTiming API is not supported, we look for the cookie where we wrote the start time, and if found, use that. This time is set to rt.tstart. If we find neither, we abort [1].

    If we find a cookie, we check the URL stored in the cookie with the document.referrer of the current document if it was set via onbeforeunload or the URL of the current page if the cookie was set via onmouseup or onsubmit. If these two differ, it means that the user possibly visited a third party page in between the two pages from our site and the measurement is invalid, so we abort [2].

    If we're still going, we pull the time out of the cookie and remove the cookie. We measure the difference in the two times (rt.end - rt.tstart) and this is the round trip time for the page.

    If the WebTiming API is supported, we check the value of responseStart. If not, we use the time of the onunload or onpagehide events stored in the cookie, and use this as a proxy for first byte time (t_fb_approx). With this, we can calculate the following entities:

    t_done
    Roundtrip time: rt.end - rt.tstart
    t_resp
    Backend time: (responseStart || t_fb_approx) - rt.tstart
    t_page
    Frontend time: rt.end - (responseStart || t_fb_approx)

2. Bandwidth & Latency measurements

Bandwidth and latency are measured by downloading fixed size images from a server and measuring the time it took to download them. We run it in the following order:

Footnotes:

  1. We don't actually abort at this point, but give the developer the ability to salvage the moment by setting his/her own start time. This is most useful when the developer isn't measuring full page load time, but possibly the load time of some dynamic content loaded via JavaScript.
  2. We offer the developer the ability to not abort at this point, but instead pass all URLs to the back end and let the server decide whether to discard the beacon or not. This is useful for sites that have a login page behind SSL and possibly redirect to the login page if the user clicks on certain links. In this case there might either be no referrer, or the referrer may not match.
  3. This value is configured using the BW.nruns parameter. See Howto #6 for details on configuring boomerang.
  4. The bandwidth test times out after 15 seconds. At that point it will try to determine the bandwidth based on data that it has already collected.