Install the Optimizely Web Experimentation snippet as a non-blocking resource

  • Updated
This topic describes how to:
  • Choose the correct attributes for deploying Optimizely Web Experimentation as a non-blocking resource
  • Avoid page flickering when deploying Optimizely Web Experimentation as a non-blocking resource

If you are looking for better page-load performance, you might consider deploying Optimizely Web Experimentation as a non-blocking resource using either defer or async. However, this sometimes causes page flickering, which in turn can generate sub-optimal user experiences.

This article will outline the various considerations around loading Optimizely Web Experimentation as a non-blocking resource.

We strongly recommend that you do not deploy your Optimizely Web Experimentation snippet as non-blocking. These instructions are intended as a last resort, and should not be followed unless you have no other option.

Choose the right attribute for the snippet’s script tag

Loading the Optimizely Web Experimentation snippet as a non-blocking resource (or “less-blocking,” in the case of async) requires using either the defer or async attribute on the script tag. Each attribute induces different loading behavior from the snippet, so be sure you choose the one that’s most appropriate.

The defer attribute:

  • Will load the script over the network in parallel to DOM parsing

  • Once the snippet is fetched, script execution will wait until after the browser parses the DOM (immediately after PerformanceNavigationTiming.domInteractive and prior to DOMContentLoaded)

  • Guarantees the script will be executed in the order in which it appears in the document, relative to other defer scripts

  • Does not guarantee the script will be executed in the document order relative to synchronous scripts

  • Does not guarantee to be non-render-blocking

blockinggraphic1.png

Example:

<script src="https://cdn.optimizely.com/js/12345678.js" defer></script>

The async attribute:

  • Will load the script over the network in parallel to DOM parsing

  • Will execute the script immediately after the snippet is fetched, blocking DOM parsing during execution

  • Does not guarantee the script will be executed in the order in which it appears in the HTML, relative to all scripts

  • Does not guarantee to be non-render-blocking

blockinggraphic2.png

Example:

<script src="https://cdn.optimizely.com/js/12345678.js" async></script>

Load the snippet programmatically via JavaScript

If you want to ensure the snippet is entirely non-render-blocking, you could load it programmatically via JavaScript, via the window.onload handler. Window.onload waits until after the entire page has been fully loaded before firing. This includes all external resources, like images, CSS, scripts, etc.

However, loading Optimizely Web Experimentation this late in the page-rendering process will have other negative impacts, especially relating to pageview and bounce/exit metrics tracking, and the ability to employ a flicker-management solution.

Example:

window.addEventListener("load", function() {
 var loadScript = document.createElement('script');
 loadScript.src = 'https://cdn.optimizely.com/js/PROJECT_ID.js';
 document.head.appendChild(loadScript);
});

Prevent page flickering

To prevent page-flicker, you will have to mask either the entire page or the portions of the page that your experiment will affect.

To do this, apply visibility: hidden to certain elements in the DOM, and then remove that rule once after the Optimizely Web Experimentation client has been initialized and has applied synchronous variation changes.

Here is a technical guide that outlines how to employ a masking solution.

Page flickering is only an issue with above-the-fold visual experiments—those that are visible as soon as the page loads. Some examples where page flickering may not be a concern include:

  • Experiments that take place below-the-fold

  • Experiments that take place after some visitor action, like triggering a popup modal

  • Experiments where the snippet is deployed down-funnel, for tracking purposes only

Impact on metrics and integrations

Since async and defer affect the predictability of the snippet’s execution timing, it is critical to understand how adding these attributes to your snippet tag might affect your experiment.  

Both implementations can potentially lead to broken analytics or audience integrations due to timing issues. Be sure to audit your integrations before deploying the Optimizely Web Experimentation snippet to production using async / defer:

  • When deploying Optimizely Web Experimentation using defer, the snippet generally executes later in the page-load, which means that it is likely to affect your ability to accurately measure pageview and bounce/exit metrics. The benefit of using defer is that order of execution will be enforced whenever there are other dependency scripts being loaded with defer.

  • When deploying Optimizely Web Experimentation using async, it is difficult to manage the order of execution against other dependencies.

You may have to refactor any integration code relying on Optimizely Web Experimentation’s getter methods (e.g., get-visitor) to ensure that those API methods are available when they are called. This is best handled with the lifecycle event listener activated.