Hydration means the framework attaches event handlers and state to HTML the server already sent. The page looks ready at once. But to hydrate, the browser must download, parse and run the JavaScript for every component on the page, and React must render the whole tree again in memory.
The costs:
- Big JavaScript bundles, even for parts that never change, like a footer or an article body.
- Long tasks while hydrating, so the page looks ready but ignores clicks. This is sometimes called the uncanny valley.
- Bad INP and slow interactivity on cheap phones.
Ways to reduce it:
- Islands (Astro, Fresh): the page is static HTML by default. Only the interactive parts, the islands, ship JavaScript and hydrate. A blog post with one like button hydrates only the button.
- Selective hydration (React 18 and later): wrap parts in
<Suspense>. React hydrates each part on its own, and hydrates first the part the user interacts with. - React Server Components: Server Components render only on the server and send no JavaScript. Only
"use client"components hydrate. - Lazy hydration: hydrate a widget only when it scrolls into view or the browser is idle.
- Resumability (Qwik): skip hydration by saving the state into the HTML and loading handlers only on interaction.
The common idea: send JavaScript only for the parts that are interactive.
- Hydration downloads and runs JavaScript for every component, then renders the tree again.
- The page can look ready but ignore input while hydration runs.
- Islands ship JavaScript only for the interactive parts of a static page.
- Selective hydration hydrates
Suspenseboundaries on their own, and first the one the user interacts with. - Server Components send no JavaScript, so only client components hydrate.