Table of Contents
970 words
5 minutes
Frontend Rendering Patterns: Differences and Choices Between CSR, SSR, and SSG

1. Introduction#

When you open a website, where does the HTML you see come from?

This question seems simple, but the answer determines a website’s performance, SEO, and user experience. The core question of frontend rendering modes is: when and where is the HTML generated?

Rendering ModeHTML Generation TimingGeneration Location
CSRAfter the browser loads JSClient side (browser)
SSROn every requestServer
SSGAt build timeServer (one-time)

2. CSR: Client-Side Rendering#

2.1 Workflow#

Browser requests URL
↓
Server returns an almost empty HTML (only one <div id="root"></div>)
↓
Browser downloads JS Bundle
↓
JS executes, generates HTML and inserts it into the page
↓
✅ Page is interactive

2.2 A Typical CSR Page#

<!-- HTML returned by the server -->
<!DOCTYPE html>
<html>
<head>
<title>My SPA</title>
</head>
<body>
<div id="root"></div>
<script src="/bundle.js"></script>
</body>
</html>

What the browser receives is an empty shell; the actual page content is dynamically generated on the client side by bundle.js.

2.3 Pros and Cons#

AdvantagesDisadvantages
Low server pressure (only returns static files)Longer first-screen blank time (waiting for JS to load)
Smooth page transitions (SPA, no refresh)Poor SEO (search engines may not see the content)
Simple development, clean frontend-backend separationPoor experience on low-performance devices
Suitable for CDN deploymentTime to First Byte (TTFB) does not equal time to interactivity

2.4 Use Cases#

  • Admin management systems, dashboards
  • Single-page applications (SPAs) requiring heavy interactivity
  • Pages that are not SEO-sensitive

3. SSR: Server-Side Rendering#

3.1 Workflow#

Browser requests URL
↓
Server executes JS / renders components
↓
Server generates complete HTML (including data)
↓
Browser receives complete HTML → renders directly
↓
JS "hydration", page becomes interactive
↓
✅ Page is interactive

3.2 A Simple SSR Example (Node.js)#

import { renderToString } from 'react-dom/server';
app.get('/article/:id', async (req, res) => {
const article = await db.getArticle(req.params.id); // Query the database
const html = renderToString(<ArticlePage data={article} />);
res.send(`
<!DOCTYPE html>
<html>
<head><title>${article.title}</title></head>
<body>
<div id="root">${html}</div>
<script src="/bundle.js"></script>
</body>
</html>
`);
});

The HTML the user receives already contains the complete content; they can see the text without waiting for JS to load.

3.3 What Is Hydration?#

The HTML returned by SSR is static — buttons are visible, but clicking does nothing. The browser needs to load JS and “attach” event listeners to the existing DOM. This process is called Hydration.

Server-rendered HTML (a dry, bare page)
+ JS loading + event binding
= an interactive page (it's "alive")

3.4 Pros and Cons#

AdvantagesDisadvantages
Fast first screen — directly returns HTML with contentHigh server pressure (must render on every request)
SEO-friendly — search engines can crawl the complete contentSlower TTFB (server rendering takes time)
Friendly to low-performance devicesComplex deployment (requires a Node.js server)
Users can see content fasterFirst-screen visibility does not mean interactivity (Hydration takes time)

3.5 Use Cases#

  • Content-oriented websites (blogs, news, e-commerce detail pages)
  • SEO-sensitive pages
  • Scenarios requiring fast display, such as homepages

4. SSG: Static Site Generation#

4.1 Workflow#

At build time:
Read data (Markdown / API / CMS)
↓
Pre-render all pages into pure HTML
↓
Output static files to dist/
At request time:
Browser requests URL
↓
CDN / static server directly returns the pre-generated HTML
↓
✅ Extremely fast response

4.2 How SSG Works#

// Runs at build time, generates static HTML
export async function getStaticPaths() {
const posts = await getAllPosts();
return posts.map(post => ({
params: { slug: post.slug }
}));
}
export async function getStaticProps({ params }) {
const post = await getPost(params.slug);
return { props: { post } };
}

4.3 Pros and Cons#

AdvantagesDisadvantages
Extremely fast — it’s just pure HTMLContent updates require rebuilding
Can be deployed to a CDN, with nearly zero server costLong build times when there are many pages
Best SEONot suitable for real-time data (such as personalized user content)
Highest security (no server-side logic)The number of dynamic route pages must be determined in advance

4.4 Use Cases#

  • Technical blogs, documentation sites
  • Corporate websites, marketing pages
  • Landing pages
  • Sites with infrequently changing content

5. Comparison of the Three Modes#

DimensionCSRSSRSSG
First-screen speed⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
SEO⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Server load⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Interactive experience⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Real-time data⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Build time⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Deployment complexitySimpleMediumSimple

6. Hybrid Approaches in Modern Frameworks#

Real projects rarely use only one rendering mode. Modern frameworks such as Next.js, Nuxt, and Astro support mixed usage:

Within the same project:
/about → SSG (content does not change)
/blog/[slug] → SSG (articles are generated at build time)
/dashboard → CSR (personal dashboard after logging in)
/search?q= → SSR (search results vary from person to person)

Next.js Rendering Strategies#

// SSG: default behavior, generated at build time
export default function AboutPage() {
return <div>About Us</div>;
}
// SSR: regenerated on every request
export const dynamic = 'force-dynamic';
// ISR: Incremental Static Regeneration — SSG + scheduled updates
export const revalidate = 3600; // Regenerate every 3600 seconds (1 hour)

Astro’s Islands Architecture#

Astro defaults to SSG but supports “interactive islands” within pages:

---
// This part runs at build time
const posts = await getAllPosts();
---
<!-- Static content, output HTML directly -->
<h1>My Blog</h1>
{posts.map(post => <article>{post.title}</article>)}
<!-- "Island": this component renders on the client, preserving interactivity -->
<LikeButton client:load />
<CommentSection client:visible />

7. How to Choose a Rendering Mode?#

A simple decision flow:

Will the content change frequently?
├── Yes → Need real-time data + SEO?
│ ├── Yes → SSR
│ └── No → CSR
└── No → Is SEO important?
├── Yes → SSG
└── No → Either CSR or SSG works

Or start from the page type:

Page TypeRecommended ModeReason
Blog postsSSGContent rarely changes after writing; just build and leave it
Product detail pagesSSG + ISRDescriptions stay the same; price/stock can be refreshed periodically
Search results pagesSSRResults differ for each query
User dashboardsCSRPersonalized content after login, no SEO needed
HomepageSSGDisplay-oriented content, pursuing ultimate speed
Real-time data dashboardsCSR / SSRRequires real-time refresh

8. Summary#

The essential difference between the three rendering modes can be summed up in one sentence each:

ModeCore Question
CSRHTML is generated in the browser → server is relaxed, first screen is slow
SSRHTML is generated on the server (on every request) → first screen is fast, server is burdened
SSGHTML is generated at build time → first screen is fastest, content stays put

No mode is a “silver bullet.” The trend in modern frontend frameworks is mixed usage, letting each page choose the rendering approach that suits it best. Understanding these three modes is a key step in your journey from “writing pages” to “designing architecture.”

Frontend Rendering Patterns: Differences and Choices Between CSR, SSR, and SSG
https://www.hehonglei.com/technology/frontend-rendering-csr-ssr-ssg/
Author
HHLBlog
Published at
2026-06-17
License
CC BY-NC-SA 4.0