Picture this - you’re starting a new project, maybe a shiny portfolio site or a chance to play with some trendy new tech. But with so many frameworks and libraries out there, you’re paralyzed by choice. So you Google “React vs Vue vs Angular”, hoping the wisdom of the crowd will tell you which is best.
You start reading an article, but get a bit confused by certain words - hydration? Server-side rendering? Prerendering?
So you close the tab, unenlightened. Frustrated, you just go with SolidJS because you saw a post tweet from your dev crush about using it for their portfolio.
It doesn’t have to be this way. Let’s break it down simply.
Hydration - in a nutshell, this is using client-side JavaScript to make static HTML interactive. Hydration takes plain HTML from the server and adds state and interactivity with JS on the client. This is a core feature of frameworks like React. Dan Abramov says “Hydration is like watering the “dry” HTML with the “water” of interactivity and event handlers.” Perhaps an analogy may help, I like food, so let’s go with a food analogy - think of hydration like adding sauce to pasta. You start with plain, unseasoned pasta, al dente (static HTML). It’s edible sure, but bland. Then you add zesty tomato sauce (client-side JS). Now you have a complete, flavorful meal!
For websites, hydration “sauces up” your static HTML by adding interactivity and logic with JS. But there’s a catch - adding sauce takes time. This is why fully hydrated pages have a higher Time To Interact (TTI).
This brings us to Partial Hydration. Rather than drench the whole plate, you strategically sauce parts that need flavor. For websites, this means only hydrating sections that need JS logic, keeping TTI fast.
let’s take a look at some quick examples;
//EXAMPLE ONE
import React from "react";
export default function App() {
const [count, setCount] = React.useState(0);
return (
<div>
<p>I don't need to be interacted with</p>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
//EXAMPLE TWO
import React from "react";
function Counter() {
const [count, setCount] = React.useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
export default function App() {
return (
<div>
<p>This text is static HTML.</p>
<Counter />
<p>This is also static HTML.</p>
</div>
);
}
Can you tell how each block of code is hydrated ?
In the first example, the entire page is fully hydrated using React logic. It includes both static elements and interactive elements. However, in the second example, only the Counter component is selectively hydrated with interactivity, while the surrounding elements remain as static HTML. This demonstrates partial hydration, allowing you to add interactivity where needed and maintain cleaner, more modular code.
In summary, hydration is good - it brings static sites to life. But partial hydration lets you sprinkle interactivity where you need it, avoiding unnecessary delays.
Server-Side Rendering (SSR) - Server-Side Rendering is essentially when you render your application’s HTML on the server, rather than the client. But what does that really mean ? time for another food analogy!
Server-side rendering is like having a restaurant cook your meal before you arrive. This way, when you get to the restaurant, your food is already prepared and can be served to you right away.
For example, imagine you order a cheeseburger from a restaurant’s website. Here’s what happens behind the scenes;
The server (restaurant kitchen) receives your order request and immediately starts cooking up a fresh cheeseburger with all the fixings.
While the burger is sizzling on the grill, the server also prepares the plate with sides like fries and coleslaw.
Once the burger is fully cooked and plated, the server packages it all up and sends the ready-to-eat meal to your table.
When you (the client browser) receive the meal, you can start eating immediately without having to wait for any preparation or cooking.
In code, this process looks something like:
// Server side
app.get("/cheeseburger", (req, res) => {
// Cook up burger and prepare plate (render HTML)
const html = ReactDOMServer.renderToString(<Cheeseburger />);
// Send prepared meal to the client
res.send(html);
});
// Client side
const root = document.getElementById("root");
// Plate already prepared, just display it
root.innerHTML = html;
Compare this to Client-Side Rendering which can be interpreted in code like this;
// Server side
app.get("/cheeseburger", (req, res) => {
// Send raw ingredients to the client
res.send(burgerIngredients);
});
// Client side
const root = document.getElementById("root");
// Assemble and cook the burger
makePatty(ingredients.beef);
cookPatty(patty);
assembleBurger(bun, patty, ingredients);
// Burger is finally ready to eat
root.innerHTML = <Cheeseburger />;
So in summary, server-side rendering pre-cooks your app’s content on the server so it’s served up instantly on the client side. This results in faster load times since the client doesn’t have to wait for any JavaScript processing.
I believe understanding these concepts help you write better code, so next time you see a word you’re not familiar with while going through documentation or an article, find out what it really means, it really helps!
And remember, you can’t learn everything at once, one line of code at a time!