Anti-Flicker

How Coframe prevents a flash of original content while variants load

Guide~2 min read

Copy this guide and your current settings as a prompt for your AI agent.

Preview agent promptSee the guide, code and settings included when you copy.

When Coframe applies a personalized or experiment variant to a page element, there is a window between when the browser first paints the page and when the SDK has finished fetching and applying its changes. Without any protection, visitors can briefly see the original content before it is replaced — a “flash of original content” that can look jarring and undermine the credibility of a variant-driven experience.

The anti-flicker mechanism addresses this by hiding the page until the SDK has either applied its changes or a timeout has elapsed.

Watch: 42s — the same page loaded with and without anti-flicker, slowed 10×, plus the timeoutMs fallback
On this page
  1. 01How It Works
  2. 02Why It Must Be Installed Synchronously
  3. 03Timeout Behavior
  4. 04When Anti-Flicker Is Disabled

01How It Works

Anti-flicker hides <body> immediately on page load using a CSS variable, then reveals it once the SDK has applied its changes or timeoutMs (default 1000 ms) has elapsed — whichever comes first.

The CSS variable approach lets the reveal be animated with a short opacity transition:

JS
// Coframe antiflicker CSS
const style = document.createElement('style');
style.id = 'coframe-antiflicker';
style.textContent =
  ':root { --cf-show: 0;}' +
  'body { opacity: var(--cf-show) !important; transition: opacity 0.2s ease; }'

function hide() { document.head.appendChild(style); }
function show() {
  document.documentElement.style.setProperty('--cf-show', '1');
  style.parentNode && style.parentNode.removeChild(style);
}
hide(); setTimeout(show, config.timeoutMs);

When the SDK applies its changes, the body is revealed and the hiding style is removed. If the SDK fails to load for any reason, show() is still called, so the page is never permanently stuck in a hidden state.

02Why It Must Be Installed Synchronously

The anti-flicker snippet must run synchronously, before the browser paints content for the first time. If it is loaded through an async tag manager — or added with an async or defer attribute — the browser may already have painted the original content before the snippet runs, which means the first flash will have already occurred before the snippet can hide anything.

This is different from the main SDK script, which can be loaded asynchronously. The anti-flicker snippet is small by design and intentionally blocks the page parse for a brief moment so it can guarantee that body is hidden before paint.

03Timeout Behavior

The timeoutMs setting controls the maximum time the page will remain hidden. The default is 1000 ms. After that window closes, show() is called regardless of whether the SDK has finished applying changes.

This is a fail-open design: if the SDK is slow or unavailable, visitors will see the original content rather than a hidden page. The tradeoff is that in worst-case network conditions a visitor may briefly see unmodified content before a variant is applied, but the page is never stuck in a blank state.

You can tune the timeout through the SDK configuration. See SDK Options for the full list of runtime settings, including timeoutMs.

04When Anti-Flicker Is Disabled

Anti-flicker is automatically disabled when the SDK is running in trackingOnly: true mode. In tracking-only mode the SDK does not apply any content changes, so there is no variant to hide during load. Keeping anti-flicker active in that mode would add unnecessary latency without any benefit.

Related reading

Content and video lessons from Coframe documentation. Code examples are not executed on this page.

BACK TOPerformance

Documentation

Open Coframe App

Search documentation

Search all guides and references↑ ↓ Navigate · Esc Close