DEV Community

Cover image for 🧠 Hydration, Selective Hydration & Progressive Hydration Explained (React vs Vue/Nuxt vs Others)
Vishwark
Vishwark

Posted on

🧠 Hydration, Selective Hydration & Progressive Hydration Explained (React vs Vue/Nuxt vs Others)

Hydration is one of the most important concepts in modern frontend frameworks, yet also one of the most misunderstood.

In 2025, frameworks like React 18+, Vue/Nuxt 3, SvelteKit, SolidStart, Qwik, Astro all approach hydration differently — some progressively, some selectively, some partially, some never fully.

This post breaks it all down with real examples, SSR + SSG scenarios, and an extended example so the concept stays in your mind forever.


🌊 What Is Hydration?

When a page is SSR or SSG, the browser gets plain HTML:

<div id="app">
  <button>Click me</button>
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
  </ul>
</div>
Enter fullscreen mode Exit fullscreen mode

But HTML alone does nothing — no JavaScript, no event listeners.

Hydration is when the framework:

  • Loads JS bundles
  • Recreates the virtual component tree
  • Attaches event listeners
  • Activates reactivity
  • Makes the page interactive

Another way to say it:

SSR/SSG gives HTML.
Hydration gives life.


🟥 Old Hydration Model (Pre-React 18 / Classic Vue / SvelteKit)

Traditionally, hydration happened linearly, top-to-bottom:

1. Hydrate App()
2. Hydrate Header()
3. Hydrate Navbar()
4. Hydrate Sections()
5. Hydrate Footer()
Enter fullscreen mode Exit fullscreen mode

Linear hydration has three big problems:

❌ 1. Slow Time-To-Interactive

Because hydration must finish before the user can interact safely.

❌ 2. Big JS bundle runs all at once

Blocks main thread.

❌ 3. Offscreen components hydrate early

Even things not visible yet.

This model works, but it’s outdated for large apps.


🟩 React 18+: Selective Hydration (Smarter, Not Linear)

React 18 replaced “hydrate everything in order” with:

Hydrate what’s needed, when it’s needed.
Skip or delay the rest.

React evaluates multiple signals:

React 18 automatically detects:

  • Which components are visible
  • Which components are interactive
  • Which have pending Suspense data
  • Which are above-the-fold
  • Which the user interacts with first
  • Which are heavier or lower priority

Hydration priority:

1️⃣ Visible + interactive components
2️⃣ User-clicked or user-focused components
3️⃣ Above-the-fold content
4️⃣ Suspense boundaries that resolved
5️⃣ Below-the-fold or non-interactive UI
6️⃣ Everything else, when browser is idle

This is selective hydration — only hydrate the parts users need immediately.


🟦 How Suspense Affects Hydration

Consider:

<Suspense fallback={<LoadingUser />}>
  <UserProfile />
</Suspense>
Enter fullscreen mode Exit fullscreen mode

React can stream HTML in chunks:

  • Server streams <LoadingUser /> first
  • Later streams <UserProfile /> when data resolves
  • Client hydrates these boundaries independently
  • Hydration can happen in the middle, out of order, or scattered

Suspense creates natural hydration islands.


🔥 BIG Real-World Example (SSR + Suspense + Complex Layout)

Imagine a dashboard:

+----------------------+
| Navbar               |
+----------------------+
| Sidebar | Chart      |
|         | (Suspense) |
|         |            |
+----------------------+
Enter fullscreen mode Exit fullscreen mode

Server Output (HTML)

  • Navbar rendered immediately
  • Sidebar rendered immediately
  • Chart is slow → Suspense fallback is sent

Client sees:

Navbar (interactive instantly)
Sidebar (interactive instantly)
Chart loading skeleton…
Enter fullscreen mode Exit fullscreen mode

Hydration (React 18):

1️⃣ User clicks sidebar → React hydrates sidebar immediately
2️⃣ Navbar is visible → hydrate early
3️⃣ Chart fallback hydrates next (lightweight)
4️⃣ Actual Chart component hydrates only when its data resolves
5️⃣ Footer hydrates when browser is idle

This is selective, scattered, priority-driven hydration.


🟨 Is Progressive Hydration Needed in React?

React 18 already does a form of progressive hydration:

✔ Selective hydration
✔ Suspense boundary hydration
✔ Hydrate-on-interaction
✔ Hydrate-visible-first
✔ Hydrate background content later
✔ Hydrate streaming chunks as they arrive

React does not call it “progressive hydration,” but practically, it achieves that behavior.


🟩 SSG + Hydration — Does Hydration Still Happen?

Yes.

SSG also needs hydration because:

  • HTML is static
  • But JS must still attach event handlers
  • Framework re-runs components on client
  • Event listeners get connected
  • State becomes reactive

Example:
A static blog page still hydrates “Like Button”, comments, interactive parts.

SSG = static HTML + hydration on client.


🔰 How Other Frameworks Handle Progressive Hydration

Now let's compare how different frameworks hydrate:


🟦 Vue 3 (Classic) — Linear Hydration

Vue's default hydration is still linear unless using advanced tooling.

Hydration flow:

1. Hydrate root instance
2. Hydrate children in DOM order
3. Hydrate nested components
4. Finally hydrate leaf nodes
Enter fullscreen mode Exit fullscreen mode

Downsides:

  • Slower interactivity for large pages
  • No Suspense-driven hydration
  • No hydrate-on-interaction by default

But this changes with Nuxt 3


🟩 Nuxt 3 — “Progressive, Island-Style” Hydration

Nuxt 3 introduced partial hydration capabilities, similar to islands architecture:

client:only

Component is only hydrated when needed:

<client-only>
  <FancyChart />
</client-only>
Enter fullscreen mode Exit fullscreen mode

✔ Async Components + Suspense

Nuxt 3 supports Suspense-like behavior:

<Suspense>
  <UserProfile />
</Suspense>
Enter fullscreen mode Exit fullscreen mode

This allows:

  • above-the-fold hydration first
  • async component hydration later
  • streamed HTML + partial hydration

✔ Nuxt + Nitro + Island Optimizations

Nuxt aggressively optimizes hydration for:

  • per-component hydration
  • hydration skipping for static parts
  • “hybrid island architecture”

While it's not as automatic as React's selective hydration,
Nuxt 3 can achieve progressive hydration with explicit patterns.


🟧 SvelteKit — Progressive Hydration by Default

SvelteKit hydrates:

  • visible sections first
  • interactive sections first
  • lazy components when needed

Svelte also supports component-level hydration:

  • preload only what's visible
  • lazy load everything else
  • hydrate only when scrolled into view
  • hydrate on interaction

Very efficient because Svelte compiles away most framework runtime.


🟦 SolidStart — Fine-Grained Hydration

Solid uses reactive primitives and compiles away components.
Hydration happens:

  • per DOM node
  • per reactive signal
  • not per component

This makes hydration extremely granular.

SolidStart naturally does progressive + selective hydration.


🟣 Qwik — No Hydration (Resumes Instead)

Qwik doesn’t hydrate at all.

It resumes the app from HTML with embedded state.
Event listeners are attached lazily.

Progressive hydration is built-in because Qwik doesn't hydrate entire trees — it loads behavior on demand.


🌑 Astro — Island Architecture (Hydrate Only What You Ask)

Astro hydrates components only when instructed:

<Counter client:load />
<Chart client:visible />
<Sidebar client:idle />
Enter fullscreen mode Exit fullscreen mode

Modes:

  • client:load
  • client:visible
  • client:idle
  • client:media
  • client:hover

A pure island architecture.
Astro minimizes JS for non-interactive content, best-in-class for performance.


🟩 Summary: How Frameworks Hydrate

Framework Hydration Style Notes
React 18+ Selective, priority-based, Suspense-aware Automatic
Vue 3 classic Linear Simple but slower
Nuxt 3 Partial/Client-only/Islands Supports progressive hydration
SvelteKit Progressive Hydrates visible/interacted UI first
SolidStart Fine-grained Tiny hydration chunks
Qwik No hydration → Resume Most advanced
Astro Islands Hydrate only what you choose

🎉 Final Thoughts

In modern SSR/SSG frameworks:

  • Hydration is the cost of interactivity
  • Linear hydration is slow
  • Progressive + selective hydration is the future
  • React 18+ achieves it automatically
  • Nuxt 3, SvelteKit, Qwik, Astro each do it differently
  • Suspense brings async-shaped hydration
  • Streaming SSR improves TTFB dramatically

If you understand hydration deeply,
you understand the foundation of modern web frameworks in 2025.


Top comments (0)