So: “To SSR or to CSR?”. That seems to be the question. But wait, how did we even get here? What’s the difference between Server-Side Rendering (SSR) and Client-Side Rendering (CSR)? And why should you even care?
What’s CSR Anyway
To understand Client-Side Rendering, we have to go back to ice-age of the internet — I’m talking AOL CDs arriving in the mail. “You’ve got Mail!” as the whole family rushed towards the family computer.
Back then, web pages were akin to magazine articles. A static page was created at design time, and bundled together in a folder. So, when you clicked a link, we simply retrieved one of those pre-baked pages for you. Everytime!
<html>
<head>
<title>The Best Car in Town</title>
</head>
<body>
<h1>Introducing the CyberTruck 1996</h1>
<p>The Absolute best in modern automotive Engineering money can afford</p>
<p>Price: $5000</p>
</body>
</html>
But then with social media websites like Facebook gaining massive success, it became clear that we needed a more personalized experience on the web. Something less like a magazine and more like a conversation.
So we came up with dynamic, database-driven pages - written in PHP! That is you clicked a link, and even though a new page was freshly loaded for you, at least it was personalized to the content that made sense just for you.
<?php
// Define the $car array with a price
$car = array('price' => 50000);
// Output the HTML content
echo '<html>';
echo ' <head>';
echo ' <title>The Best Car in Town</title>';
echo ' </head>';
echo ' <body>';
echo ' <h1>Introducing the CyberTruck 1996</h1>';
echo ' <p>The Absolute best in modern automotive Engineering money can afford</p>';
echo ' <p>Price: $' . $car['price'] . '</p>';
echo ' </body>';
echo '</html>';
?>
But then, as the web grew, so did the complexity of the pages. We started to notice that the server was doing a lot of work. It was like asking your grandma to run a marathon. Ok, maybe that’s a bit harsh, but the (early) browsers were never designed for that amount of processing.
Enter JavaScript Frameworks. Frameworks like jQuery Backbone.js and Ember opted to move all of the rendering logic to the browser - or the client in this case - hence, Client Side Rendering.
In Client-Side Rendering (CSR) with React, the browser downloads a minimal HTML page and the JavaScript needed for the page. The JavaScript is then used to update the DOM and render the page. When the application is first loaded, the user may notice a slight delay before they can see the full page, this is because the page isn’t fully rendered until all the JavaScript is downloaded, parsed, and executed. - NextJS
The results? Revolutionary! Everyone and their mum created one. We’re talking a web experience that went from slow and clunky, to snappy and responsive. With loading spinners, no full page reloads, the web suddenly became faster, fluid and generally more exciting.
So, what changed?
It turned out CSR was never a silver bullet solution to rendering web apps. Although, coming to think of it, is there even a silver bullet in Software Development? Anyway, some serious red flags started popping up as we stuffed everything to the client side:
- SEO: Ever tried to impress Google with a site full of JavaScript widgets? Yeah, good luck with that.
- Performance: In CSR, your browser does all the work. It’s like asking your grandma to run a marathon. Ok, maybe that’s a bit harsh, but the (early) browsers were never designed for that amount of processing.
- Initial Load: You click a link, and then you wait… and wait. CSR has that slow first punch, and in the web world, just like on Tinder, first impressions actually do count.
Enter SSR
Server-side Rendering looked at the growing list of CSR limitations and said, “Hold my Sobo.” Instead of sending a blank or skeleton HTML and waiting for the client to do the rest, SSR sends a fully-rendered page from the server.
“But didn’t you just say that’s how old versions of Facebook worked?” - you ask
Yes, Maestro, you got it. Here’s the nuance: while old-school web pages sent a fully-rendered HTML page for every new request (just like SSR), those pages were often static or server-script generated. They didn’t provide a dynamic, single-page app experience.
SSR took the idea of sending a fully-rendered HTML page and jazzed it up. It combined the best of both worlds: the SEO-friendly and speedy initial load of traditional server-rendered pages, and the dynamic interactivity of client-side apps.
(SSR allows us to) render the same components into HTML strings on the server, send them directly to the browser, and finally “hydrate” the static markup into a fully interactive app on the client. - VueJS
The magic is in the word “hydrate” - a topic for another blog post!
Ok, great, so we can go home right?
No. Remember what I said about Silver Bullets? Well SSR isn’t one either. Here are some practical short-comings I’ve found as I SSR my web apps:
Context - No Globals
If you’ve coded with the assumption that window
or document
objects are available, SSR will be a rude awakening. You see, these browser-specific objects don’t exist in a Node.js environment. You might encounter the infamous ReferenceError: window is not defined.
// Example code causing a ReferenceError
if (window.innerWidth > 768) {
// Do something awesome
}
You might want to use conditionals to check for the existence of browser-specific objects.
if (typeof window !== "undefined" && window.innerWidth > 768) {
// Do something awesome
}
Server Management
With SSR, you’ve cracked open the gates to the server realm like Neo entering the Matrix. Suddenly, the “client” and “server” aren’t just theoretical concepts or responsibilities divided on a Jira board. Nope, they’re both yours to command.
You see, SSR doesn’t just require you to understand how to send rendered HTML to the client. Oh, it’s much deeper than that. We’re talking HTTP status codes, request and response objects, middleware, server configurations, and don’t even get me started on handling APIs and databases.
So put on your dual hat of both frontend magician and backend sorcerer because you’re not just dabbling in JavaScript and CSS anymore. You’re wielding the mighty Node.js (or whatever your server-side language of choice is), diving deep into databases, and choreographing APIs like a Broadway director.
TTV vs TTI
Time to View (TTV) and Time to Interact (TTI) are like the opening act and the main event of a concert. SSR might get your users in the door quickly (fast TTV), but that doesn’t mean they’ll be able to enjoy the show right away (delayed TTI). They might see the content but have to wait to interact with it, like being at a concert but having to wait for the main act to start.
Sigh, so how do I know what to choose?
No worries, Maestro, I’ve gone out to create a basic decision tree (keyword - basic) that could guide you when trying to make the decision for your next big Web App:
Hi 👋 I'm Jeremiah. I'm Mobile and #AI 🪄 Lead at @IremboGov by ☀️ and create https://t.co/sZ4UrAssGl by 🌙
— Chienda (@liwucodes) January 13, 2024
I love to #buildinpublic and share my failers and occasional wins on https://t.co/nAroIneVbE. Let’s #connect if interested in #softwareengineering #blockchain #startups
Stay up to date with my Posts
Get notified whenever I publish a new article concerning the latest in Software Engineering, a Youtube Video or just some thoughts about politics or Faith!
You may also be interested in
7 Practical Ways to Write Rich Frontends without Javascript today
Developers have a love-hate relationship with Javascript. On the one hand, it is a vibrant community that is always evolving in its quest to quench an ever-parching thirst for users to do magic in web browsers.
Read MoreTrust me, your site is not complete - Here's why you need to re-write if for Accessibility
While accessibility is a broad topic on its own, the good news is that by adhering to Semantic HTML, you can start being accessible today. Here's a few heuristic I use everyday that help me write more semantic HTML
Read More