Rendering Strategies in Modern Web: CSR, SSR, and SSG

Jie HanJie Han
4 min read

This is a quick recap of my effort to catch up on modern frontend trends, particularly the renaissance of Server-Side Rendering (SSR), and how it compares to Client-Side Rendering (CSR) and Static Site Generation (SSG).

I’ve organized this post as personal study notes first, followed by an AI-generated summary. Here are the key questions I asked myself:

  • Do I care about SEO?

  • How big is my app, user base, or company (eng & infra team)?

  • How complex is my app? What’s the size of the current JavaScript bundle (assuming a typical CSR SPA)? Would reducing it meaningfully improve load times?

  • Are my users sensitive to loading speed, or is a loading spinner on first visit acceptable?

  • Is it worth the effort to maintain a new server (for SSR) alongside the existing backend, and ensure its observability and scalability?

  • If my backend is already written in TypeScript or Node.js, does it make sense to merge frontend and backend logic into one SSR-enabled repo (e.g. with server components)?

  • Is there a benefit to adopting a hybrid SSR + CSR approach?

My Takeaway

SSR brings meaningful gains for larger applications and companies where load time, SEO, and performance are top priorities. For small to medium projects, it only makes sense if:

  • I already use JavaScript/TypeScript across the stack.

  • I adopt a unified framework like Next.js or Nuxt.js to co-locate backend logic and avoid managing an additional server.

  • I’m developing a mobile app that needs to run on older devices, which are more sensitive to large JavaScript bundles and heavy client-side logic. In this case, offloading processing to the server and reducing the client bundle size can improve performance and user experience.

If my backend is written in another language and my users aren’t performance-sensitive, sticking with a CSR SPA is likely good enough. Hybrid SSR + CSR is also a practical option to improve initial page loads without going all in on SSR.

OK, below is AI generated comparison :)


🔍 What Are CSR, SSR, and SSG?

MethodWhere HTML is renderedWhen HTML is generatedWho renders contentIdeal For
CSR (Client-Side Rendering)In the browserOn each page loadClient (JS)Highly dynamic apps, dashboards
SSR (Server-Side Rendering)On the serverOn each requestServerPersonalization, SEO pages, blogs
SSG (Static Site Generation)During build timeBefore deploymentServer (once)Marketing pages, docs, blogs

🧠 Summary of Trade-offs

FeatureCSRSSRSSG
Initial Load SpeedSlower (wait for JS)Faster (HTML pre-rendered)Fastest (cached HTML)
SEO SupportPoor by defaultGoodGreat
PersonalizationEasy (client state)Easy (server logic)Difficult (static only)
Hosting SimplicityVery simple (S3/CDN)Needs server runtimeSimple (S3/CDN)
Real-Time DataEasyWorks with hydrationNeeds client-side fallback
Cold Start RiskNoneSome (if serverless)None
Build ScalabilityGreatGoodMay be slow for many pages

✅ Sweet Spot for Each

🟩 CSR:

  • Use when interactivity is king: dashboards, apps with lots of user state and real-time changes

  • Simpler hosting with static site delivery + APIs

🟦 SSR:

  • Use when you need:

    • SEO for dynamic content (e.g. product pages)

    • Personalized HTML per request (e.g. user-specific data)

  • You can selectively SSR certain pages (hybrid routing)

🟨 SSG:

  • Use when content is mostly static or doesn’t change per user

  • Lightning-fast delivery via CDN

  • Ideal for blogs, documentation, and marketing sites


🔬 Core Web Vitals & How Rendering Affects Them

📏 Definitions

  • TTFB (Time To First Byte): Time until the browser receives the first byte of response

  • FCP (First Contentful Paint): Time until the first text/image is rendered

  • LCP (Largest Contentful Paint): Time until the largest visible element is rendered

  • CLS (Cumulative Layout Shift): Measures visual stability (layout jumps)

  • INP (Interaction to Next Paint): Measures responsiveness of interactions

📊 Rendering Impacts

Vitals MetricCSR ImpactSSR ImpactSSG Impact
TTFBFast (static HTML)Slower (server computes)Fastest (pre-built)
FCPSlower (wait for JS)Faster (HTML sent early)Fastest
LCPSlowerBetterBest
CLSRisky (hydration jumps)Can be stableStable
INPGood (interactive)Good post-hydrationGood post-hydration
0
Subscribe to my newsletter

Read articles from Jie Han directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Jie Han
Jie Han