Prompt
How do I fix A/B test flicker on a client-side website experiment?
Latest observation
A/B test “flicker” usually means users briefly see the original page before the experiment variation loads and swaps in. The fix is to make the right variant appear before first paint or prevent the page from rendering until the experiment decision is known.
Here are the main ways to fix it, from best to most practical:
1) Move experiment assignment to the server
Best solution.
- Decide the variant on the server.
- Render the correct HTML immediately.
- Send the variant in the initial response.
Why it helps: the browser never sees the “wrong” version.
Use when: you control the backend or can add edge/server middleware.
2) Preload the experiment decision as early as possible
If it must be client-side:
- Load the experiment script in the
<head> - Avoid
defer/asyncif the script must run before paint - Keep the decision logic extremely small and fast
- Inline a tiny bootstrap script that:
- reads a cookie/localStorage value
- assigns the variant
- applies a class/attribute to
<html>immediately
Example pattern:
<head>
<script>
(function () {
var variant = localStorage.getItem('exp_homepage') || 'control';
document.documentElement.classList.add('exp-' + variant);
})();
</script>
</head>
Then your CSS can hide/show variant-specific elements.
3) Hide the affected content until the experiment is ready
Common “anti-flicker” pattern.
Add a temporary CSS rule:
<style>
.ab-hidden { opacity: 0 !important; }
</style>
Then:
- add a class like
ab-hiddento the target container immediately - remove it once the experiment variant is applied
Caution:
Don’t leave content hidden too long, or you’ll hurt performance and user experience. Use a short timeout as a fallback.
4) Use a “swap-safe” design
Instead of replacing lots of DOM after load:
- Make variants differ by CSS class, text placeholders, or feature flags
- Use the same layout dimensions
- Avoid inserting/removing large blocks after initial paint
Why it helps: less visible layout shift and less chance of flicker.
5) Optimize the experiment script
If the client-side decision is slow, the flicker gets worse.
Check for:
- Large vendor script bundles
- Network latency
- Blocking on analytics calls
- Waiting for consent before deciding the variant
- DOM queries that run too late
Improve by:
- shrinking the script
- inlining the decision logic
- caching the assignment
- deferring nonessential analytics until after the variant is set
6) Pre-assign and persist the variant
If the user has already been bucketed:
- store the assignment in cookie/localStorage
- reuse it on every page load
- apply it instantly before rendering
This avoids re-randomizing and reduces flicker.
7) Use a timeout fallback
If the experiment engine fails to load, don’t keep the page hidden forever.
Example behavior:
- hide content briefly
- after 100–300 ms, show default content if the experiment isn’t ready
This is a tradeoff: a tiny flicker is better than a blank page.
Practical recommendation
If you want the most reliable fix:
- Assign variants on the server/edge if possible
- Otherwise, inline a tiny head script to apply the variant immediately
- If needed, hide only the targeted element briefly, not the whole page
- Persist the bucket so repeat views are instant
What to avoid
- Loading the experiment script after the page content renders
- Hiding the whole page for too long
- Doing variant assignment after
DOMContentLoadedorwindow.onload - Changing major layout structure on the client after paint
If you want, I can give you:
- a generic anti-flicker snippet
- a React/Next.js version
- or advice for a specific tool like Optimizely, VWO, LaunchDarkly, Google Optimize-style setups, or AB Tasty.