Install the snippet as a non-blocking resource

  • Updated
  • Optimizely Web Experimentation

For better page-load performance, 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.

You should 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:

  • Loads the script over the network in parallel to DOM parsing.
  • After the snippet is fetched, script execution waits until after the browser parses the DOM (immediately after PerformanceNavigationTiming.domInteractive and prior to DOMContentLoaded).
  • Guarantees the script is executed in the order in which it appears in the document, relative to other defer scripts.
  • Does not guarantee that the script is 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:

  • Loads the script over the network in parallel to DOM parsing.
  • Executes the script immediately after the snippet is fetched, blocking DOM parsing during execution.
  • Does not guarantee the script is 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

To ensure the snippet is entirely non-render-blocking, load it programmatically via JavaScript, via the window.onload handler. Window.onload waits until after the entire page is fully loaded before firing. This includes all external resources, like images, CSS, scripts, and so on.

However, loading Optimizely Web Experimentation this late in the page-rendering process has 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 after the Optimizely Web Experimentation client initializes and applies synchronous variation changes. See how to employ a masking solution.

Page flickering is only an issue with above-the-fold visual experiments—those that are visible when 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

Because 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 is 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 (such as get-visitor) to ensure that those API methods are available when they are called. This is best handled with the lifecycle event listener activated.