Storefront Lab HQ
A/B testing playbooks for Shopify merchants

Test Flicker: The Flash of Original Content That Corrupts Your A/B Test

Flicker is the flash of the original page a visitor sees for a split second before the test variant loads, and most teams file it as a cosmetic annoyance. It is not. It is a validity bug, and CXL classes it among the standard threats to a test's internal validity. The damage has three mechanisms. Exposure contamination: the test assumes each user experienced exactly one version, but a flickering user experienced both, so the clean comparison the statistics depend on no longer describes what happened. Attention subsidy: motion attracts the eye, so an element that visibly swaps draws attention the static control never received, and part of any measured lift may be the flicker itself, an effect that disappears the moment you ship the winner properly. Trust erosion: a page that visibly rearranges itself reads as glitchy, and Kameleoon's analysis is blunt that flicker can push conversions below your baseline, which means the act of testing made the site worse for half your traffic. The fix is not the anti-flicker snippet, which converts visible flicker into invisible delay. It is to decide the variant before the HTML reaches the browser, or to load the snippet directly in the head, as early as possible, not through a tag manager.

Three ways flicker corrupts the data

The definition is simple: the visitor briefly sees the control before the treatment loads. The damage is not simple, and it has three distinct mechanisms. Exposure contamination is the first. The experiment's logic assumes each user experienced exactly one version. A flickering user experienced both, so the clean comparison the statistics depend on no longer describes what actually happened in their session. The second is an attention subsidy. Motion attracts the eye. An element that visibly swaps draws attention the static control never received, so part of any measured lift may be the flicker itself, an effect that disappears the moment you ship the winner properly. The third is trust erosion. A page that visibly rearranges itself reads as glitchy. Kameleoon's analysis is blunt about the business consequence: flicker can push conversions below your baseline, which means the act of testing made the site worse for half your traffic. The risk is not that the test looks ugly. The risk is that you implement changes based on tainted data from visitors who experienced the flash, and the changes lower conversions below baseline.

Where it comes from

The causes are infrastructure, not bad luck. The testing tool loads asynchronously and loses the race against rendering: the browser can display the original interface before the experiment script arrives and replaces it. The snippet is loaded through a tag manager instead of directly in the head, adding a hop you do not control. Too many scripts queue ahead of it. The site itself is slow, stretching every one of those windows. Or the variant code waits on an element with a slow detection strategy, which is a latency question about MutationObservers versus polling. Each cause is a delay between the paint and the variant, and the delay is the flicker. Neither is free. The only approach with no tradeoff is to decide the variant before the HTML reaches the browser.

The snippet trade, and the real fix

The industry's standard countermeasure is to hide the page, usually the whole body, until the testing tool has decided which variant to show, then reveal it. This works, in the sense that the user never sees the swap. What it costs is load experience: Google Optimize's default anti-flicker snippet held the page blank for up to four seconds if the tool was slow to respond, and Simo Ahava's verdict was to steer clear of snippets that hide the entire page. DebugBear's performance analysis reaches the same place: anti-flicker body hiding directly degrades page speed metrics, and slow pages have their own well-documented conversion cost. So the snippet does not remove the problem; it converts visible flicker into invisible delay. The real fix is server-side. A server-side test returns the assigned version directly, avoiding a client-side replacement after the page appears, and edge middleware routing does the same with no noticeable latency. If the variant injects a banner, reserve that banner's height via CSS in the base code, which keeps CLS at zero. And validate before deploying: use PageSpeed Insights or Lighthouse in staging to compare the control against the variant, and check that CLS stays below 0.1 in both versions. A test that degrades performance can cancel out any conversion gains and harm search rankings through Core Web Vitals, which is a second way a test can make the site worse while it claims to be measuring an improvement.

Related reading

Readers working through “Test Flicker: The Flash of Original Content That Corrupts Your A/B Test” often find these earlier guides useful as well: Heatmaps Lie by Omission: What Session Recordings Catch Instead, Statistically Significant and Commercially Worthless: The A/B Test Trap, and Peeking at A/B Tests: Why Checking Daily Breaks Your P-Value.

Frequently asked questions

What is flicker in A/B testing?

Flicker, also called flash of original content or FOUC, is when the visitor briefly sees the control before the treatment loads. The browser paints the original page, then the experiment script arrives and replaces it with the assigned variant. The human brain processes images in about 13 milliseconds, per a 2014 MIT study, so even a brief flash registers. The visitor saw both versions, and the test's assumption that each user experienced exactly one version is broken.

Why is the anti-flicker snippet not a real fix?

Because it converts visible flicker into invisible delay. The standard countermeasure hides the page, usually the whole body, until the testing tool has decided which variant to show, then reveals it. Google Optimize's default anti-flicker snippet held the page blank for up to four seconds if the tool was slow to respond, and Simo Ahava's verdict was to steer clear of snippets that hide the entire page. DebugBear's analysis reaches the same place: body hiding directly degrades page speed metrics, and slow pages have their own well-documented conversion cost. The snippet does not remove the problem. It trades one cost for another.

What causes flicker?

Infrastructure, not bad luck. The testing tool loads asynchronously and loses the race against rendering. The snippet is loaded through a tag manager instead of directly in the head, adding a hop you do not control. Too many scripts queue ahead of it. The site itself is slow, stretching every one of those windows. Or the variant code waits on an element with a slow detection strategy. Each cause is a delay between the paint and the variant, and the delay is the flicker.

How do I run a test without flicker?

Decide the variant before the HTML reaches the browser. Server-side testing removes the problem entirely, because the server returns the assigned version directly and nothing is replaced after the page appears. Edge middleware routing does the same thing with no noticeable latency. If you must test client-side, load the testing snippet directly in the head, as early as possible, not through the tag manager, and reserve space for anything the variant injects, so the page does not jump and add a layout shift on top of the flicker. For redirect tests, use a temporary 302 redirect, not a permanent 301, and never show Googlebot a different set of URLs or content from what human visitors see.