How the Optimize runtime works

Learn about what happens in your visitor's browser and how changes are applied.

There are three steps of the Optimize runtime that take place every time that a visitor comes to your site, which are covered below.

In this article:

Synchronous and asynchronous download

While the synchronous installation is simplest and ensures the highest performance for your experiences, Optimize can also operate asynchronously and this is great news, since it will not affect the regular functioning of your site. The Optimize container will download in parallel with other scripts and resources of your page and will not block them: other scripts that have downloaded first, will be able to run without a delay.

But you need to keep in mind that Optimize is typically modifying the content of your own page, so its priority is important.

This is why we recommend positioning the Optimize installation at the top of the <HEAD> to run as soon as possible, without being blocked by other scripts and libraries on your page.

Incorrect positioning of Optimize may cause flicker, a longer hiding period, and container timeouts (if you're using the anti-flicker snippet).

Anti-flicker snippet

A common issue whenever JavaScript code modifies an HTML page is flicker: visitors are able to transiently see the original version of the page, before it becomes modified.

With a tool like Optimize, this could cause confusion to your visitors and even make them realize that they are part of an experiment, with effects to your site as well as to experiment results. This is why Optimize has a number of different mechanisms to ensure that this does not happen.

A first level of defense in order to achieve this, is the anti-flicker snippet which is necessary because of Optimize's asynchronous nature.

While a synchronous script will block the browser from parsing and displaying the page (and can even stop your site from loading completely), an asynchronous script can run at any time, even after the page is visible, and it can’t be catastrophic (e.g. block your site from loading), however an asynchronous script can cause flickering.

The anti-flicker snippet temporarily hides your web page until the Optimize container has enough time to download. There is no performance hit to the typical web page with the anti-flicker snippet installed correctly because the Optimize container will download in parallel with other scripts and resources of the page that may block it from rendering.

The anti-flicker snipper isn't the only mechanism used by Optimize to avoid flickering since it will typically end before the page is actually available by the browser, in order to be modified by Optimize.

Note: The anti-flicker timeout does not indicate overhead that Optimize adds to your page; it is just a worst case scenario. Furthermore, the recommended timeout value does not relate to the performance of your site or Optimize, but mainly to your visitors network speed (e.g. in case of poor signal reception etc).

If the Optimize container (and other page resources) haven't downloaded and run on the visitor’s device before the timeout value is reached, the page hiding ends and any Optimize experiments that may apply later are abandoned and the visit is excluded from the experiment traffic.

Once the Optimize container has downloaded the global page hiding ends, the container evaluates experiment rules and ensures that only the elements involved in any chosen variant remain hidden. This can happen even if those elements are not on the page yet.

Page-hiding-snippet-flow-diagram

Targeting rule evaluation

Once the Optimize container has downloaded, it will evaluate the targeting rules of any experiments configured to be activated with the default "page load" option. Experiments that have non-default activation configured will wait for their activation events.

Note: The experiment model page used to launch the Optimize editor is not relevant to targeting (even though it is initially assigned as the default targeting rule). To see exactly which rules apply to an experiment, you need to look to the targeting tab of the experiment details page.

A visitor will be assigned to a variant during their first visit to a page after the experiment has started – this doesn’t have to be their first visit to that page, however. The assignment is random (based on the Google Analytics client ID), following the variant weights. The visitor will remain in the assigned variant until the end of the experiment while actions that happen any time later (i.e. goals) are attributed to that variant.

The variant assignment is stored in a dedicated first-party cookie (_gaexp) and will be used on future visits of the same visitor, to ensure a consistent experience. This doesn’t mean that the visitor will necessarily see the variant on following visits; every time the rules are re-evaluated, but if they match, the user will see that same variant. Note though, that conversions on that or any other page will be attributed to that variant regardless of rules.

If a visitor is exposed to multiple running experiments (on any page), those assignments are concatenated on the same cookie. Due to browser limitations on cookie size there is a maximum number of concurrent experiments that a user can be assigned to. When a visitor's cookie exceeds that limit they are excluded from experiment traffic and they will not see variants of additional experiments. Once an experiment has ended, its variant assignments are cleaned up and the visitor is eligible to be added into additional experiments.

Once a visitor has been assigned to an experiment, the runtime will ensure that the necessary variant information is tracked by Google Analytics. For experiments activated with the default “page load” configuration (and not using custom activation) , the variant assignment happens before the Google Analytics pageview hit and experiment tracking takes place using that hit. In other cases (or if you haven’t followed the recommended Optimize installation) there will be an additional Google Analytics data hit to ensure experiment tracking.

Changing experiment weights does not assign visitors. Even if you set a variant weight to zero, there may still be traffic to one of your variants from visitors that were assigned to it before the weight change.

Experiments are independent from each other. A single visit can participate in multiple experiments and you need to avoid side-effects. While it is perfectly normal to run multiple experiments on the same page, these should be done on different page areas to avoid the introduction of bias (e.g. where the variant of one experiment promotes a variant of another experiment).

Note: Optimize variants are applied "best effort" – if some of the CSS selectors in your variants don’t exist, or your JavaScript changes have exceptions, the visit will still be measured as part of the experiment variant.

Finally, some of your targeting rules may be evaluated on the server side, resulting in completely pruning the experiment from the downloaded container.

Targeting rule evaluation flow diagram

Application of chosen A/B and MVT variants

Once the container has chosen its variants, it will attempt to apply them. A variant is defined as a list of change operations (shown in the Optimize editor) which are generally applied in order (there are some optimizations when there are no conflicts).

Each change is targeting a CSS selector that may correspond to one or more elements. Optimize knows if a change is targeting multiple elements, since this is detected by the editor.

Often the element of a change will not be available in the page at the time that Optimize runs. In such a case Optimize will ensure that it remain hidden once it becomes available, by adding a necessary CSS rule and will then pause the change list execution.

As soon as that target element becomes available, Optimize will apply the change, remove the hiding CSS rule, and attempt to apply the following change in the list in the same manner.

Once the browser has change the page status to ready (after the DOMContentElement event), Optimize will do a last best effort to apply all remaining changes. If the element of a change can’t be found at this point, Optimize will simply ignore it and move on.

Note: Style changes are typically implemented with CSS rules so they don’t need to go through the above process. Instead they are applied immediately as soon as Optimize loads and there is no need for additional hiding.

JavaScript changes have a target CSS selector as well, and will run once the element of this selector has become available by the browser.

Implementing an entire variant with a single JavaScript change (i.e. using jQuery) on <BODY> isn't recommended in Optimize since your code may run later than you intended. Try to restrict the target selector of a JavaScript to the elements that you want to modify, or the smallest possible parent container element.

Finally, a change may have a CSS selector that targets multiple elements (the Optimize editor supports selecting multiple elements by shift clicking) which may appear in a page at different times. Optimize will change them as they appear but will lift the hiding for all of them at the end.

Application of variants flow diagram

If you use custom events to activate your experiment the targeting rules are not evaluated once, when the page loads, but instead every time that your send an activation event. The first time that the rules will be matched the visitor will be assigned to a variant, a Google Analytics hit (typically a data hit) will be sent to ensure experiment tracking and the variant changes will be applied.

Unlike with the case of the default page-load activation though, this will not be the end of the work of the runtime. Typically you should send more activation events, every time that there is a significant change on the page’s state (i.e. Url or DOM tree. When this happens there are two possibilities:

  • The targeting rules are still matched and in that case the variant is “reactivated”: the runtime will re-run the changes of your variant but will apply them only to new elements which were not available on the previous run.

  • The targeting rules are not matched and in that case the variant is “deactivated”: changes will be reverted and the elements will be put back in the state they were before those were applied. For each event all deactivations happen before activations, so that the page goes back to its original state in order to be ready to apply correctly the new experiment. Note though that javascript changes can’t be reverted automatically.

Related resources

Was this helpful?
How can we improve it?