Anti-Flicker & SSR
Prevent content flashing during split test assignment
Last updated:
The SDK uses a three-tier approach to prevent content flashing when split test assignments load.
Tier 1: localStorage Cache
On repeat visits, the SDK reads cached assignments from localStorage synchronously before making any network calls. This means returning visitors see the correct variation instantly with no flicker.
Caching is on by default. You can control cache behavior with staleTTL and maxAge:
await SplitTesting.init({
publicApiKey: 'YOUR_PUBLIC_API_KEY',
propertyId: 'YOUR_PROPERTY_ID',
staleTTL: 60000, // refresh in background after 1 minute
maxAge: 86400000, // expire cache after 24 hours
});staleTTL: After this many milliseconds, the SDK serves the cached value immediately but fetches fresh config in the background. Default is0(always refresh in background).maxAge: After this many milliseconds, the cache is considered expired and the SDK waits for a fresh fetch before resolving. Default is86400000(24 hours).
To manually clear the localStorage cache (e.g., during development or after a test is reconfigured):
// Wipe cached config and assignments for this property
SplitTesting.clearCache();Tier 2: SSR Bootstrap
Pass pre-evaluated assignments from the server to skip the network call entirely on the client. This gives you zero flicker and zero latency on first visit.
Server
// Server-side: evaluate assignments
import SplitTesting from '@sessionsight/split-testing';
await SplitTesting.init({
publicApiKey: 'YOUR_PUBLIC_API_KEY',
propertyId: 'YOUR_PROPERTY_ID',
});
const bootstrap = SplitTesting.getAssignments();
// Pass 'bootstrap' to the client (e.g., inject into the HTML as JSON)Client
// Client-side: use pre-resolved assignments
await SplitTesting.init({
publicApiKey: 'YOUR_PUBLIC_API_KEY',
propertyId: 'YOUR_PROPERTY_ID',
bootstrap, // from the server
});
// No network call needed. Assignments are available immediately.
const headline = SplitTesting.get('hero-headline', 'Welcome');The SDK still fetches fresh config in the background to keep the cache warm for subsequent page loads.
Tier 3: Anti-Flicker Snippet
For cases where neither cache nor bootstrap is available (first visit, no SSR), enable the anti-flicker option to hide elements until assignments resolve.
await SplitTesting.init({
publicApiKey: 'YOUR_PUBLIC_API_KEY',
propertyId: 'YOUR_PROPERTY_ID',
antiFlicker: true,
});Then mark the elements that depend on split test values with data-ss-split:
<h1 data-ss-split>Welcome to Acme</h1>
<div data-ss-split id="pricing">...</div>When antiFlicker is enabled, the SDK injects a <style> tag that sets visibility: hidden on all [data-ss-split] elements. Once assignments are resolved, the style tag is removed and elements become visible with the correct content.
Only elements with
data-ss-splitare hidden. The rest of your page loads normally.
Choosing a Strategy
| Scenario | Recommended approach |
|---|---|
| Returning visitors | Automatic (localStorage cache handles it) |
| Server-rendered pages (Next.js, SvelteKit, etc.) | SSR bootstrap |
| Static sites, first visit | Anti-flicker snippet |
| API-only backends, no SSR | Anti-flicker snippet |