Improving Snippet Performance and Matching with 3rd Party Analytics
/events Logging Endpoint: Better performance through batching
Our customers care a lot about the performance impact of including our snippet in their web frontend. We’re constantly improving our snippet to make it faster, and we’re happy to announce the /events endpoint: a new logging endpoint for the Optimizely X Web snippet.
Today, our snippet generates one network request per event to be tracked, and there are a lot of events being tracked on any page including:
- Decision events (one per activated experiment)
- Pageview events (one per Page activated)
- Conversions events (clicks, custom events, etc.)
We know that each network request has an impact on page performance, especially during the critical first seconds of page load. This is especially important on mobile devices where each request consumes finite data and battery resources.
A few things happen when a snippet is configured to use the /events endpoint:
- As events are triggered, they are appended to a localStorage queue
- Events are pulled off the queue, batched together and sent once per second for the first ten seconds after snippet activation
- Any events that are triggered after this point will be sent immediately, without queueing or batching
- Note: using the /events logging end point may result in a slight decrease in the numbers of unique visitors and conversions displayed on the Optimizely results page as some visitors who load a page and then bounce within the first second will not be tracked
These optimizations may sound simple, but they have the potential to deliver pretty astonishing performance improvements. One of our early adopters reported that:
“[The new snippet] went live this morning. It reduced page load by a full second. That made quite an impact! Keep these changes and improvements coming!”
holdEvents and sendEvents: Granular control over event logging
In addition to improved performance, we’ve also added the ability to control the timing of when the snippet starts to generate requests.
- Call holdEvents before the snippet initializes to prevent any events from being logged
- Call sendEvents later on to start dispatching events
So why would a developer want to control the timing of Optimizely event logging? Two common use cases are:
- You want to further optimize page load performance by delaying event logging more than one second
- You want to align the timing of Optimizely’s tracking with third-party analytics
This second use case is really important, and something we think about a lot at Optimizely. We know that our customers expect the numbers on Optimizely’s results page to line up with their analytics solution, which is often the “source of truth” for the metrics they care about most. When we diagnose analytics discrepancy issues, we often find that the root cause is a mismatch in timing of event logging between Optimizely and third-party analytics, where Optimizely begins logging events earlier during page load. By calling holdEvents before the Optimizely snippet begins logging events and then calling sendEvents part of a callback method provided by third party analytics, it’s possible to significantly reduce this timing gap.
Originally, without this update, Optimizely events could be sent before and after 3rd party events. This made it harder to align Optimizely with 3rd party analytics tools as shown in the image below.
With batching in the new snippet, fewer network requests are generated, and request timing is delayed to be closer to that of third-party analytics..
Finally, using the holdEvents and sendEvents methods in conjunction with batching can align the timing of events to happen closer to the timing of third party analytics tools to reduce data discrepancies.
One of our customers implemented these APIs in an effort to more closely align their Optimizely results with those of their analytics platform. Prior to implementation, Optimizely was showing ~12% more unique visitors. Today, Optimizely’s count of unique visitors is within 3% of the analytics platform, which our customer considers within the acceptable margin of error.
One thing to keep in mind is that implementing these features will have an impact on experiment results. Because these features prevent Optimizely from logging events immediately, there will be some number of visitors who “bounce” from your website before any events are logged. This could lead to a decrease in the number of unique visitors and conversions displayed on the results page. To mitigate this factor, snippets using the /events endpoint use a localStorage queue for unsent events, enabling Optimizely to log events generated when a visitor quickly navigates to another page where the snippet is implemented. So the only time the snippet would fail to track events entirely is if the visitor triggered events and then exited your site before those events could be logged.
Ok, so if you’re as excited about these new features as we are you’ll probably want to get started using them right away. These features are now generally available and fully supported, but you need to opt-in to get access. Here’s how it works:
- Submit a support ticket requesting access (optimizely.com/support).
- Our support team will enable access to the new features in your account.
- The next time any snippet associated with your account is resaved, it will begin using the new logging endpoint.
- You can then start calling holdEvents and sendEvents. Note that any calls to these APIs prior to enabling the new logging endpoint will have no effect.
We’ll be rolling these new features out to all snippets by default in January of 2018, but if you’d like to get your hands on them now go ahead and opt-in!
Head on over to our Knowledge Base and Developers site for more information:
- KB: Identify the logging endpoint used by a snippet
- KB: Control the timing of event dispatch with holdEvents and sendEvents
- KB: Check event firing for snippets using the /events logging endpoint
- Dev Docs: holdEvents
- Dev Docs: sendEvents
- Dev Docs: Troubleshoot Events and Tags for snippets using the /events endpoint