The Evolution of Web Rendering: SSG, SSR, CSR...
The web evolving, we aren’t living in a world of simple static website anymore. There are a lot of options for developers nowaday: SSG, SSR, CSR,…
Each of the rendering technique has unique set of pros and cons, so choosing the right one for your project is important.
So in this post, we’ll explore some popular rendering techniques, discuss about the pros and cons, and help you choose the right one for your next project.
Static site generator (SSG)
First, what is a static website:
A website that was built using HTML, CSS files. It serves the same content for every client at the same time
It has little to no interactivity
SSG is a technique to generate a full static HTML website based on templates and some data. Those pages could later be stored on a storage provider and served to the client quickly via a CDN. You could host it on a server if you want, but not necessary.
Example of implementing SSG using Next.js
export default function Blog({ posts }) {
// Render list of posts base on received data.
}
// This function gets called at build time
export async function getStaticProps() {
// Call an external API endpoint to get posts
const res = await fetch('https://.../posts')
const posts = await res.json()
// By returning { props: { posts } }, the Blog component
// will receive `posts` as a prop at build time
return {
props: {
posts,
},
}
}
Pros:
You don’t need to worry about database load when the site traffic increases.
Could handle site load more efficiently through a CDN provider.
Cons:
- Changing the site content requires the rebuild process of the whole site - there might be a cloud provider or framework minimize this build process to only the changing content, but I haven’t figured it out yet @@
Server-side rendering (SSR)
(Source https://prismic.io/blog/what-is-ssr)
SSR is a technique that server will render all HTML, CSS, JS and send it to the client. After receiving the static asset, client will start the hydration process to add the interactivity.
SSR is popular in many old to modern frameworks. That's actually how we built interactive websites from the early '90s. Perl and PHP are popular web languages at that time @@
Benefits:
Faster initial loading time: The server renders everything ahead of time and sends it to the client
Search engine optimization friendly, why? Because most crawling engines work effectively with HTML-based content.
Improved performance for slow devices: usually client had to render the HTML page based on the JS loaded file, this technique run slower on slow or old devices. SSR will perform better because it renders all HTML pages and sends them to client.
Cons:
Could increase load to the server. SSR had to render all HTML page for each request, so more client, more load to the server.
Complex to setup: setup this technique yourself is not easy, both because of the rendering on client, server and the hydration process. So you should use many popular frameworks out there: Next.js, Remix.js,…
Client-Side Rendering (CSR)
CSR is a technique that uses Javascript render function to generate the whole website on browser. Most of the rendering process will happen on client. And for rendering, I mean render your HTML page.
How it works: the server will send small HTML files with many Javascript files to handle rendering of the whole site.
CSR will be used for a website with content changing rapidly, different from user to user. So it’s best to build a client application, typically a complex one.
Pros:
Reduced server load
Best interactivity, all actions will happen almost immediately on the browser, providing best user experience
Cons:
This could lead to longer page load time due to how big your JavaScript file is - you could reduce it by using lazy loading
Poor SEO, even though crawler engine are improving the process of indexing Javascript-loaded websites, it’s still having a hard time dealing with it. Having HTML website could make your site indexing faster.
Has dependency on user’s device. Each device and browser version handles Javascript execution differently. If user’s device is old and does not support the function you use, it could potentially cause bug and unexpected behavior.
Incremental Static Regeneration (ISR)
Let’s say that you have a blog or general website, you update your content usually. You need it:
SEO friendly
Run fast, can handle the load efficiently.
You don’t need the updated content show up immediately, you’re fine if there’s a little delay.
Static site rendering is fine, but the whole site needs to rebuild many times during the day, and your site contains a hundred pages ?
Server-side rendering is okay too, but what if there’s a strike in traffic and causing crash?
That when you need a solution leverage both advantages of those 2 techniques. How about a server-side rendering site, but all the pages will be cached for 5 mins?
That’s generally how Incremental Static Regeneration (ISR) works. When user request your pages, the server will render, then caching it. After a specific time frame, if there’s another request coming, the server will check and rerender the page again, then caching it.
Example of implementing ISR using Next.js
export const getStaticPaths: GetStaticPaths = async () => {
let posts = await fetch('https://api.vercel.app/blog').then((res) =>
res.json()
)
let paths = posts.map((post: Post) => ({
params: { id: post.id },
}))
// We'll prerender only these paths at build time.
// { fallback: 'blocking' } will server-render pages
// on-demand if the path doesn't exist.
return { paths, fallback: false }
}
export const getStaticProps: GetStaticProps<Props> = async ({ params }) => {
let post = await fetch(`https://api.vercel.app/blog/${params.id}`).then(
(res) => res.json()
)
return {
props: { post },
// Next.js will invalidate the cache when a
// request comes in, at most once every 60 seconds.
revalidate: 60,
}
}
ISR is great, but still has cons. It cannot be used for a site that always need the newest content - ecommerce site for example, users always want to know if your product in stock or out of stock when they visit. In this case, SSR might be the best choice.
Edge-Side Rendering (ESR)
This is probably a new technique. It works the same as Server-side rendering, except that the rendering engine isn’t Nodejs runtime, it uses edge runtime, and edge runtime uses JavaScript V8 engine.
We don’t have access to Node.js APIs when working with edge runtime.
Example of deploying an astro site to Cloudflare pages using Cloudflare worker’s runtime (edge runtime)
import { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';
export default defineConfig({
output: 'server',
adapter: cloudflare()
});
Recap
There’s a lot of options for you and me to choose, make sure to the choose the best fit.
Static Site Generation (SSG):
Best for content that doesn't change frequently
Offers excellent performance and SEO benefits
Requires rebuilding for content updates
Server-Side Rendering (SSR):
Provides faster initial load times and better SEO
Great for dynamic content but can increase server load
Frameworks like Next.js, Nuxt.js,.. make implementation easier
Client-Side Rendering (CSR):
Ideal for highly interactive applications
Reduces server load but may impact initial load time and SEO
Best for complex, dynamic web apps
Incremental Static Regeneration (ISR):
Combines benefits of static and dynamic rendering
Allows for content updates without full rebuilds
Balances performance and freshness of content
Edge-Side Rendering (ESR):
Emerging technique using edge computing for rendering
Promises lower latency and improved performance
Limited by edge runtime capabilities
Subscribe to my newsletter
Read articles from Định Nguyễn Trương directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by