What Is Hydration? Making Server HTML Interactive
Hydration is how JavaScript wakes up server-rendered HTML so static markup becomes interactive. The cost, the tradeoffs, and the modern alternatives.
Hydration is the process by which client-side JavaScript takes over a page that was rendered on the server — attaching event listeners, restoring component state, and making static HTML interactive. It’s the glue between server rendering and a dynamic user interface, and it’s responsible for some of the most important performance tradeoffs in modern front-end development.
Why hydration exists
To understand hydration, you need to understand why server rendering (SSR) and static site generation (SSG) exist in the first place.
When a server renders a page, it sends complete HTML to the browser. The browser can paint that HTML immediately — no JavaScript required. This produces a fast First Contentful Paint and helps search engines index the content. But the HTML is inert: buttons don’t respond, forms don’t validate, interactive components don’t work.
JavaScript then ships to the browser and runs. Hydration is the moment it reads the existing DOM, reconciles it with the framework’s virtual component tree, and wires up the interactivity. The page was already visible; now it’s alive.
Without hydration (or something like it), you’d have to choose between fast paint with no interactivity, or full interactivity with a slow start. Hydration tries to have both.
The cost of hydration
Full hydration has a real performance price. The browser must:
- Download the JavaScript bundle (network cost).
- Parse and compile the JS (CPU cost).
- Re-execute all the component logic to reconstruct the virtual tree.
- Walk the real DOM and attach event listeners to matching nodes.
During the gap between “HTML painted” and “hydration complete,” the page is in an uncanny valley: it looks interactive but isn’t. Clicks and taps may silently fail. This dead time directly hurts two Core Web Vitals metrics: Interaction to Next Paint (INP) and Total Blocking Time (TBT). Google uses these signals in its ranking algorithm, so hydration latency has real SEO consequences.
The larger your bundle, the longer the uncanny valley lasts. A heavy SPA that ships everything at once can have a hydration gap of several seconds on a mid-range device.

The spectrum of hydration strategies
The industry has developed several approaches to address the cost:
Full hydration
The traditional model. The entire page’s JavaScript ships on load and hydrates everything at once. React, Vue, and Svelte all default to this. It’s predictable and easy to reason about, but pays the full cost upfront.
Partial hydration and islands
The islands architecture (popularized by Astro) treats a page as mostly static HTML with isolated interactive “islands.” Only the islands ship JavaScript; the surrounding content stays inert. If 80% of your page is text and images, you’re only paying hydration cost for the 20% that actually needs it.
Astro’s client: directives let you control exactly when each island hydrates: client:load (immediately), client:idle (when the browser is idle), client:visible (when scrolled into view). This granularity is powerful for performance.
Progressive hydration
A middle ground: hydrate components incrementally, starting with the most visible or critical ones. Less all-or-nothing than full hydration, but more complex to orchestrate. React 18’s concurrent features (streaming SSR with Suspense) support this pattern natively.
Resumability
Qwik takes a radically different approach called resumability. Instead of re-running component code in the browser to reconstruct state, it serializes the entire execution state into the HTML at render time. The browser “resumes” from that snapshot rather than replaying everything from scratch. Startup cost approaches zero because no JavaScript runs until the user actually interacts with something.
React Server Components
React Server Components (RSC) blur the boundary further. Server Components render only on the server and never hydrate — they have no client-side JS at all. Client Components hydrate normally. This lets you ship a React app where most of the component tree never touches the browser’s CPU.
The connection to the DOM
Hydration is fundamentally about the DOM — the browser’s live, mutable representation of the page. If you want a deeper foundation, understanding what the DOM is will make the hydration model much clearer.
The framework’s reconciler needs to map its virtual component tree onto the real DOM nodes produced by the server. If there’s a mismatch (a hydration error), the framework either throws a warning and fixes it or, in stricter configurations, re-renders from scratch in the browser — discarding all the SSR work.
Measuring the impact
The metrics to watch:
- Time to First Byte (TTFB) — affected by how fast the server renders.
- Largest Contentful Paint (LCP) — SSR/SSG helps by getting content into HTML early.
- INP / TBT — hurt by long hydration; partial hydration or resumability helps here most directly.
The signals and frontend state wave is also relevant: fine-grained reactivity systems (SolidJS, Vue’s Vapor mode) reduce the work the runtime does during and after hydration by tracking only what actually changed.
The takeaway
Hydration is a necessary tradeoff: server rendering wins on initial paint and SEO, but making the page interactive costs CPU time and creates a window of apparent-but-not-real interactivity. Full hydration is the simplest model and often fine for small apps. For performance-sensitive work, islands architecture (Astro), progressive hydration (React 18), or resumability (Qwik) each chip away at that cost from different angles. Knowing the tradeoff helps you pick the right tool — and explains why the front-end framework landscape keeps moving.
Keep reading
Takina · · 4 min read What Is the Beacon API? navigator.sendBeacon()
The Beacon API lets a page send one last async request as it unloads, without blocking navigation or racing the browser's page teardown.
Takina · · 3 min read What Is Fetch Priority? The fetchpriority Attribute
fetchpriority lets you tell the browser which resources matter most, overriding its default heuristics to load critical assets sooner.
Takina · · 5 min read CSS will-change Explained: Compositing and Performance
The CSS will-change property hints the browser to prepare an element for an upcoming change, moving it to its own compositor layer. When to use it and when not to.