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

Asked by mitchd on 2024-06-15. Tags: react, feature-flags, flicker, performance.

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?

## 2 answers

### Answer from Gabriel Fontaine (2024-06-15)

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.

#### Reply from mitchd (2024-06-16)

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

### Answer from n_okafor (2024-06-16)

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](https://blog.croct.com/post/ab-testing-react-applications).
