Why not use sendBeacon?

One reaction to last weeks article on the ACDL was from @AnalyticsNinja, and it was about the 500ms wait time I mentioned:

So very right he is, and the only excuse I have is that … no, I don’t have an excuse. I simply didn’t think of that. Typical case of “but I always did it like that!”

That is bad and it must stop.

Framing

What is this about?

For Analytics, we track when pages load, and we track when people do things. “Do things” includes clicking, and sometimes the thing clicked is a link, meaning the browser’s natural reaction is to go and load some other page.

For us in Analytics, that posed a slight problem: we wanted the tracking call to actually happen, but the browser would simply dump the current page as quickly as possible.

Our fix for that, in the past, was to introduce a 500ms delay so the tracking call could go out before the page was destroyed.

Pre-tag management, the s.tl() method did it for us, if you passed in the clickable DOM element as the first parameter. That why you see a lot of s.tl(this, ...) out there. And if you didn’t need those 500ms, you would simply pass null, instead.

Then came DTM, then Launch, and now you can add the delay on the “Click” Event Type provided by the Core Extension.

[screenshot]
Add a delay on the “Click” Event Type in Launch Rules
To summarise: we are delaying the browser response to the click, because we need the browser to send tracking.

Sounds bad?

That’s because it is.

sendBeacon

And that’s why, at some point, the navigator.sendBeacon() method was introduced, as a way to send data even in a “dump this page” situation.

The big caveat first: Internet Explorer is not playing. No big surprise, here, I guess, given that even Microsoft is working very hard on digging a deep grave for it.

But it sounds like IE is now down to single digit percentages on most sites, so maybe that can be tolerated in exchange for a better experience for everyone else.

According to the sendBeacon documentation on MDN, all other browsers have been supporting sendBeacon for some time, now.

Browsers supporting it is just one part of the picture, the other is support in Adobe Analytics.

That was added in AppMeasurement 2.17.0, in August 2019. You can find the documentation here.

To make the Analytics Javascript use sendBeacon, you set s.useBeacon = true;, and then the next tracking call will go out via sendBeacon, easy enough.

Btw: the automatic exit link tracking uses sendBeacon, by default, which makes a lot of sense.

The Analytics Extension for Launch does not yet have any means built-in for sending a beacon using sendBeacon, at this time, though.

How to use it with Launch?

The Extension does so far not support sendBeacon in the “Send Beacon” Action Type (I’m sure I’m the only one finding that funny, on a “when Launch has launched” sort of level), and so the obvious question is: how can I use it?

I have three options for you, all workarounds.

Option 1 — Write an Extension that has a ‘Use sendBeacon for next “Send Beacon” Action’ Action Type,

Option 2 — Use a “Custom Code” Action to set s.useBeacon = true before the “Send Beacon” Action, or

Option 3 — Use a “Custom Code” Action to set s.useBeacon = true after each call to “Send Beacon”.

The least “workaround-y” workaround IMHO would be to build an Extension that provides a ‘Use sendBeacon for next “Send Beacon” Action’ Action Type. You would use that Action Type in your Rules just before the “Send Beacon” Action that sends data to Analytics.

If you’re not into writing Extensions, you can achieve the same with a “Custom Code” Action, of course. Just put that Action before the “Send Beacon” Action, and voilà!

[screenshot[
useBeacon Custom Code Action – not the best way
There is one issue, though, and it kills this idea: because the Action is a “Custom Code” Action, Launch only loads the code when it is needed, i.e. when the Rule fires. The browser, at this point, is still trying to get rid of the page as quickly as possible, and so loading the code, executing it, then moving on to the “Send Beacon” Action and actually sending the tracking call is likely going to take too long.

On subsequent occasions, the code will have been cached, but you’ll likely lose the first one. Given that often, that first time may also be the last, this option is not brilliant.

That’s where the third option comes into play: use a “Custom Code” Action Type to set s.useBeacon = true after each “Send Beacon” call.

The reasoning is this: we can track the initial page load as usual. The next tracking call may well be a link click, so let’s set s.useBeacon = true right now. That way, the reaction to the click can be faster when it happens.

Options 1 & 3 are practicable, option 2 is not. All of the options will hopefully no longer be necessary once the Analytics Extension allows us to chose in the UI.

Notes

I have a short reading list for you, about sendBeacon, and about the different events in the lifecycle of a web page.

First, the aforementioned documentation for sendBeacon on MDN — concise, simple, good for refreshing your memory on how to use it.

Second, Don’t lose user and app state, use Page Visibility by Ilya Grigorik, in which he explains how the Page Visibility API works, and why using the onunload event is not a great idea at all.

Third, Google’s developer documentation on the Page Lifecycle API, which has a metric ton of stuff, probably too much for most people on here.

Update 2021/02/19: there are a lot of reasons not to use sendBeacon.

If you are worried, check out what Simo Ahava has to say on Twitter, the discussion on the MDN article, and the numbers shown by Paul Boocock on Twitter.

This is no silver bullett.

7 thoughts on “Why not use sendBeacon?

  1. How did I miss this s.sendBeacon setting when we upgraded to 2.17?? We cannot use the click delay because it breaks many of our “links” (a separate story), so this just might be the solution for us.

    Thanks for highlighting! This is the main reason I try to read blogs like yours. At this point in my job role I simply don’t have the time anymore to comb through all of the documentation, and internalize them, when Adobe makes updates. I rely on people like you to help me with that, and you always come through with hidden nuggets.

    Liked by 1 person

  2. I have been using option 2, but was thinking about moving s.useBeacon = true to doPlugins. Just wondering about your thoughts, any reason you can think of not to do that?

    Like

    1. Hi Anton,

      That should work, sure.

      I would test a lot, though. After I posted the article, there was a discussion on the #measure slack. Not everyone thinks that the Beacons are ready for production use.

      Like

    1. I would currently not set it for _all_ hits, there is no need.

      After I wrote this article, some people told me about their less than perfect experiences with sendBeacon, so I think a) use it when necessary and b) test, test, test

      Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.