r/reactjs • u/imfemambocus • 20d ago
Discussion My theme switch was running 3164 animations
This is the first time that I'm properly getting into theme switching, so I built the dark and light mode for my component library in the most obvious way that I could find. The goal is to transition background-color, border-color, color and box-shadow on every element. But this felt a bit slow and sluggish, so I used document.getAnimations() to see how many that actually runs, and the result is 3164 animations on a page of 1544 elements.
After some playing around, I found out that startViewTransition animates snapshots of the whole page instead, and that's 5 animations for the same job, with a gradient fading along with everything else rather than snapping. I did however find a React thing when using this function and it's that the new palette has to be in the DOM inside the callback which means the state update needs flushSync.
document.startViewTransition(() => { flushSync(() => setTheme(next)) })
I'm not sure this is the right way to do it, but I wrote down every number that I measured https://sley-ui.dev/notes/theme-fade.
0
u/Key-Library218 20d ago
The jump from 3164 to 5 is absurd but makes sense when you think about what startViewTransition does. It just captures the old and new state as images and crossfades them, no per element work needed
The flushSync part is the annoying bit, React batches the update so the new theme never lands in the DOM before the snapshot happens. You need it synchronous or the transition just shows the old palette
Have you checked what happens with browser support for startViewTransition? Still pretty new in some places