Yesterday we pushed up a major update to how tracking works. The purpose of these changes is to make the code work even faster and smoother behind the scenes. 24 hours later, no sneaky issues have cropped up, so we’re officially announcing it now.

We’ve migrated most tracking-related beacons to use navigator.sendBeacon instead of appending a [script] element to the HTML document. We’ve had our eyes on this for quite a while as its purpose is literally for making tracking faster and more reliable, but there’s been very little discussion of it anywhere even though most browsers have officially supported it for years now. But earlier this year, Google announced “parallel tracking” for Google ads, which uses sendBeacon instead of redirects to track clicks on ads. Google relying on it for their revenue backbone was a sign that it was ready.

Unfortunately we had to keep the old [script] method for the initial page view, because it echoes back javascript code that needs to be executed in the scope of the page being tracked, e.g. on-site analytics, heatmaps, setting first-party cookies for inactive sites that tells our code to stop logging traffic – this isn’t possible with sendBeacon, which works outside of the page scope and is a downside in this instance. But everything after that – pings, events, goals, heatmap data, clicks on outbound or download links – uses sendBeacon, which is pretty noice.

The [script] element method has also itself been updated though so that the [script] elements are appended to document.body instead of document.head, which should have a big impact to help speed up that initial page view tracking. This change should have been made ages ago but it wasn’t until I was knee-deep in this upgrade that I learned that dynamically injected [script] elements still block, even if you create them with the ‘async’ parameter. They shouldn’t, but they can and do. Sigh.

sendBeacon = No more pauses on download and outbound links
sendBeacon works outside of page scope which, as mentioned above, has one major downside for us. But the major upside is its reliability. sendBeacon works in the background even after a page has unloaded, so tracking should be much more accurate and reliable. We’ve entirely removed the 500 millisecond ‘pause’ that we were creating for tracking clicks on download and outbound links, which was needed to give enough time (most of the time) for a round trip to our tracking servers to log the click before the page was unloaded. It was a necessary evil 10 years ago when we added this feature.

How much of humanity’s time have we collectively cost because of this pause? I’d lowball estimate we’ve tracked an average of 50 million clicks per day on download or outbound links over the last 10 years since we added this feature.
50M * 365 * 10 = 182,500,000,000 clicks x 0.5s = 91,250,000,000 seconds = 1,056,134 days = 2,893 years. Traveling back in time that many years would land you in the 9th century BC where you could travel to central Europe and witness the beginning of the Iron Age. Dude.

The code you copy and paste onto your site has also been changed. Instead of 3 versions of the code, there is now just 1, and it’s fully asynchronous by default. And it’s much simpler and more reliable than the old version of the (optional) asynchronous code. This one just uses a normal [script] element with the ‘async’ parameter embedded directly in it. It’s now 2 lines instead of ~10.

Reinstalling the code is optional, but we do recommend it to get the full benefits. Also now we recommend the code go into your [head] element instead of at the bottom of the [body] since the default code is now fully asynchronous and does not include the badge or noscript image elements (which can be added back with the checkboxes, if you add those in then put the code in [body] instead).