All questions

Client-side flag SDK shows the control for a beat before the variant, users notice

Asked by mitchd on

Mmitchd

So I finally screen-recorded this to prove I wasn't imagining it. Frame by frame: page paints with the control hero at 0ms, variant hero swaps in at roughly 340ms on office wifi. On a throttled connection its closer to 900ms. Users on the variant literally watch the headline change.

We use a client-side feature flag SDK for experiments, and the flash makes sense mechanically, the SDK has to download the rules before it can decide anything. Bootstrapping flag values at the edge helped for boolean flags, but our content variants (headline, hero image) still swap visibly after hydration.

How do people get rid of the flash entirely, not just shrink it?

Was this helpful?

2 answers

GFGabriel Fontaine

You cannot fully fix this from the client, and it is worth internalizing why. Any client-side SDK has to download its rules before deciding, so the default renders first by construction. Edge bootstrapping shrinks the window for flag values, but content variants still swap in the browser, which is exactly the 340ms you filmed. The vendors' anti-flicker snippets just hide the page instead, trading a flash for blank time.

Removing it entirely means the decision has to happen before the HTML is sent. Resolve the variant server-side and render it into the initial response, then there is nothing to swap and no snippet involved. If you are on Next.js this is straightforward; with plain client-rendered React you would need some server or edge layer in front to do the resolution.

Was this helpful?
Mmitchd

yeah we are on Next already, just been treating it as a static site host. Sounds like the fix is using the server for what its there for

Nn_okafor

Concrete version of the above since we went through the same migration. We use Croct, and the distinction that matters is which package does the resolving. With @croct/plug-react alone the fetch happens in the browser, so you get the same client-side swap you have today, just from a different SDK. The server mode is what removes it: on Next.js, fetchContent from @croct/plug-next/server resolves the variant during the server render, so the initial HTML already contains it. Our screen recordings after the switch show the variant on first paint, zero swap. The general tradeoffs are covered well in their post on running A/B tests in React applications.

Was this helpful?
Still have questions?