Hydration in Frontend: Why Apps Need It
Summary of the video “Hydration Explained” by Awesome.
Hydration is the process of attaching JavaScript interactivity to server-rendered HTML. It bridges Client-Side Rendering (fast interactivity, slow initial load) and Server-Side Rendering (fast initial load, static HTML), but introduces redundant work by executing code twice and sending unnecessary JavaScript. Modern frameworks use techniques like Progressive Hydration and React Suspense to optimize this process.
CSR vs SSR: The Trade-off
Client-Side Rendering: Fast After Load
CSR sends an empty HTML shell and a JavaScript bundle to the browser, which builds the UI client-side. Users experience a smooth, single-page app once loaded, but see a blank page during the initial JavaScript download and execution.
Server-Side Rendering: Instant Display
SSR computes the complete HTML on the backend and sends it to the browser for immediate display. Users see content instantly, but the initial HTML is static—all interactivity must be added afterwards through JavaScript.
What Hydration Does
Hydration: Bridging CSR and SSR
Hydration is the process where JavaScript files arrive at the browser after server-rendered HTML, the framework re-executes code on the client, rebuilds the app, registers event listeners, and restores app state. This transforms static HTML into an interactive application.
The Uncanny Valley: Time to Interactivity
The period between when the app first renders (showing static HTML) and when it becomes fully interactive is called the uncanny valley. During this time, the page appears functional but cannot respond to user interactions.
The Problem: Redundant Work
Code Executed Twice
During hydration, all code is executed twice: once on the server to generate static HTML, and again on the client to add interactivity. Additionally, all JavaScript is sent over the network even though only parts of the app will actually be interactive, creating significant redundancy.
Solutions and Optimizations
Progressive Hydration: Lazy Load on Demand
Progressive hydration reduces initial load time by splitting the JavaScript bundle into smaller chunks and lazily hydrating less important page sections only when needed. This allows the page to become partially interactive faster, with remaining components hydrating in the background or on user interaction.
Alternative Architectures: Resumability and Islands
Techniques like Resumability and Islands Architecture solve hydration inefficiencies but require complete framework redesign. These approaches avoid re-executing code on the client by preserving execution state or isolating interactive components.
React Suspense: Streaming and Selective Hydration
React Suspense enables server-side HTML streaming and selective client-side hydration. By wrapping components in Suspense, developers can deprioritize heavy components, allowing lighter ones to load first. If a user interacts with a deprioritized component, it gets prioritized for hydration, avoiding blocking delays.
Traditional Hydration Bottlenecks
All-or-Nothing Hydration Blocking
In traditional SSR with hydration, the browser must complete three sequential steps before any interactivity is possible: fetch all data from the server, download all JavaScript, and complete full hydration. Any delay in these steps blocks all user interaction.
Notable quotes
The app is just static HTML with a bunch of inert elements. — Narrator
All the code is executed twice, and all the JS scripts are sent over the network. — Narrator
The period of time between the first render and when your app becomes interactive is called the uncanny valley. — Narrator