Reducing Layout Shift During React Hydration
A server-rendered React page can look perfect on first paint and then jump a moment later, when hydration mounts components that were not in the server markup β a personalized header, an ad slot, a client-only carousel. Each unreserved mount pushes content down and adds to Cumulative Layout Shift, a Core Web Vital that influences ranking. This guide eliminates hydration-driven CLS and complements the hydration strategies comparison.
Step-by-step fix
-
Reserve space for client-only widgets. Give the container fixed dimensions in the server markup so the mount fills a held slot instead of pushing content.
// β Widget mounts into a zero-height container, shoving content down <div id="promo">{mounted && <Promo />}</div> // β Reserve the final size up front; no shift when it mounts <div id="promo" style={{ minHeight: 90 }}>{mounted && <Promo />}</div> -
Render auth-dependent UI consistently between server and client. Rendering a logged-out header on the server and a logged-in one after hydration shifts the layout; render a stable shell and fill details in place.
// β Same height server and client; only the label swaps <nav style={{ height: 56 }}>{user ? <AccountMenu /> : <SignInLink />}</nav> -
Size skeletons to match final content. A 200px skeleton replaced by 400px of content shifts everything below it β match the dimensions.
-
Pin web fonts with
font-display: optionalor preload to avoid a font swap reflow during hydration.
Validation
- Lighthouse β Cumulative Layout Shift under 0.1 on lab runs.
- Performance panel β Experience lane shows no shift markers after load.
- Web Vitals field data (CrUX / RUM) confirms CLS at the 75th percentile under 0.1.
- DevTools βLayout Shift Regionsβ overlay highlights nothing during hydration.
Configuration reference
/* Reserve space for hydration-mounted regions so CLS stays flat */
[data-hydrate] { min-height: var(--reserved-height, 0); }
.skeleton { height: var(--final-height); } /* match real content */
@font-face { font-family: Inter; font-display: optional; } /* no swap reflow */
Frequently Asked Questions
Why does my page shift right after it loads? Hydration mounts components that were not in the server HTML β ads, auth-dependent menus, client-only widgets β and they push existing content down. Each unreserved mount contributes to Cumulative Layout Shift. Reserving space before hydration eliminates the shift.
Does Cumulative Layout Shift affect rankings? Yes. CLS is a Core Web Vital and part of Googleβs page experience signals. A CLS above 0.1 is flagged as needing improvement and can weigh against a page in competitive rankings.
Related
- Incremental and streaming SSR for SEO β where hydration fits in the streaming pipeline.
- Hydration strategies compared β hydrate less to shift less.
- How to fix React hydration mismatch SEO warnings β the related correctness bug.
β Back to Incremental & Streaming SSR for SEO