Choosing the Right Rendering Strategy
Why This Decision Matters
Choosing the wrong rendering strategy doesn't just affect page speed — it affects server costs, SEO rankings, user experience, and developer productivity. A team that SSRs their entire marketing site is burning server budget on pages that could be static. A team that SSGs their dashboard is shipping stale data to every user. A team that CSRs their blog is invisible to search engines.
This topic ties together everything in the module into a practical decision framework you can apply to any page, in any project, today.
The Mental Model
Think of rendering strategies as delivery methods for a package.
- SSG: Pre-package everything at the warehouse and ship to a distribution center near the customer. Fastest delivery, but can't customize per order.
- ISR: Same as SSG, but the distribution center checks with the warehouse periodically to refresh stock. Almost as fast, with fresher inventory.
- SSR: Build the package on demand when the customer orders. Slower delivery, but fully customized.
- Streaming SSR: Start shipping parts of the package as they're ready — the customer gets the box and packing material while the main item is still being wrapped.
- CSR: Ship an empty box with assembly instructions. The customer builds the product themselves.
- Islands: Ship a pre-built product with a few DIY modules for the customizable parts.
- RSC: The warehouse does all the heavy assembly (Server Components), then sends a partially assembled product with a few parts that need client-side attachment (Client Components).
The Decision Tree
Walk through these questions for every page or route in your application:
Q1: Does the page content change per user?
│
├── NO (same for everyone)
│ │
│ Q2: How often does the content change?
│ │
│ ├── Rarely (weekly/monthly)
│ │ → SSG
│ │ Pre-build at deploy time. Serve from CDN.
│ │
│ ├── Periodically (minutes to hours)
│ │ → ISR (time-based or on-demand)
│ │ Serve cached, regenerate in background.
│ │
│ └── Constantly (seconds)
│ → SSR with short cache-control
│ Or stream critical data client-side.
│
└── YES (personalized)
│
Q3: Does it need SEO?
│
├── YES
│ → SSR (with streaming for slow data)
│ Full HTML in initial response for crawlers.
│
└── NO
│
Q4: How interactive is the page?
│
├── Mostly static with a few interactive widgets
│ → SSR + RSC (Server Components for data,
│ Client Components only for interactivity)
│
└── Highly interactive (dashboard, editor, tool)
→ SSR for initial load + heavy client JS
Or CSR if truly no SEO needed.
Framework Decision Matrix
Once you know what rendering strategy your pages need, choose the right framework:
Your pages are mostly... | Best framework fit
──────────────────────────────────|────────────────────
Static content, minimal JS | Astro (islands)
Static + some dynamic routes | Astro (hybrid) or Next.js
Mix of static, dynamic, personal | Next.js 15 (App Router + RSC)
Highly interactive SPA | Next.js or Remix
Performance-critical, sparse UX | Qwik (resumability)
Next.js 15 App Router: The Hybrid Default
Next.js 15 with the App Router is the most flexible because it supports every rendering strategy per route:
// Static page (SSG) — default behavior
export default async function About() {
return <AboutContent />
}
// ISR with time-based revalidation
export const revalidate = 3600
export default async function Blog() {
const posts = await getPosts()
return <BlogList posts={posts} />
}
// Fully dynamic (SSR)
export const dynamic = 'force-dynamic'
export default async function Dashboard() {
const user = await getCurrentUser()
return <DashboardContent user={user} />
}
// Streaming SSR (SSR + Suspense)
export default async function Analytics() {
return (
<div>
<h1>Analytics</h1>
<Suspense fallback={<ChartSkeleton />}>
<SlowChart />
</Suspense>
</div>
)
}
All four strategies coexist in the same Next.js project. No architectural changes, no framework swaps — just different exports on each page.
Decision Criteria Deep Dive
1. Data Freshness Requirements
"Stale data is fine for minutes/hours" → ISR
"Must be fresh on every request" → SSR
"Must reflect changes within seconds" → SSR + on-demand revalidation
"Real-time (sub-second updates)" → SSR initial + WebSocket/SSE client-side
2. Personalization Level
"Same for everyone" → SSG or ISR
"Varies by region/locale" → SSG per locale or ISR
"Varies by auth/user" → SSR
"Partially personalized (small widget)" → ISR/SSG + client-side fetch for widget
Or RSC + Server Islands (Astro)
3. SEO Requirements
"Critical for SEO (landing, blog, docs)" → SSG, ISR, or SSR
"Needs basic SEO (title, description)" → SSR minimum
"No SEO (behind auth)" → CSR is acceptable
(but SSR still preferred for perf)
4. Performance Targets
"Sub-100ms TTFB" → SSG (CDN edge)
"Sub-500ms TTFB" → ISR or SSR with edge runtime
"Instant TTI (zero JS)" → Astro islands or Qwik
"Best INP (interaction responsiveness)" → Minimal client JS (RSC, islands)
Real-World Architecture Examples
Example 1: Developer Documentation Platform
Route | Strategy | Why
─────────────────────────|───────────|────────────────────
/ | SSG | Marketing homepage, rarely changes
/docs/[...slug] | ISR (1h) | Docs update on publish (webhook revalidation)
/playground | CSR | Interactive code editor, no SEO needed
/blog | ISR (1h) | Blog listing, new posts trigger revalidation
/blog/[slug] | ISR (1h) | Individual posts, webhook on publish
/dashboard | SSR | User-specific, shows API usage
/search | SSG+CSR | Static shell, client-side search with Pagefind
Example 2: E-Commerce Platform
Route | Strategy | Why
─────────────────────────|─────────────────|────────────────────
/ | ISR (5min) | Featured products change periodically
/products | ISR (60s) | Inventory counts need reasonable freshness
/products/[id] | ISR (60s) | Product details + on-demand revalidation
/cart | SSR + streaming | Personalized, real-time inventory validation
/checkout | SSR | Security-critical, personalized
/account | SSR + streaming | User data, order history (stream slow parts)
/blog | SSG | Marketing content, changes rarely
Example 3: Social Media Feed
Route | Strategy | Why
─────────────────────────|────────────────────|────────────────────
/ | SSG | Landing/marketing page
/feed | SSR + streaming | Personalized feed, stream posts progressively
/[username] | ISR (5min) | Public profiles, shared across viewers
/[username]/post/[id] | ISR (60s) | Individual posts, comments update periodically
/messages | SSR + WebSocket | Real-time messaging, SSR initial load
/settings | SSR | User-specific settings
/explore | ISR (5min) | Trending content, same for everyone
The Cost Analysis
Rendering strategy directly impacts your infrastructure bill:
Strategy | Compute per request | CDN cacheability | Monthly cost at 1M visits
────────────|─────────────────────|──────────────────|──────────────────────────
SSG | Zero (static file) | 100% | ~$5-20 (CDN only)
ISR | Rare (on revalidate)| ~95% | ~$10-30
SSR | Every request | 0% (without cache)| ~$50-500
CSR | Zero (static shell) | 100% (shell) | ~$5-20 + API costs
SSR at scale is expensive. If you SSR a marketing page that gets 500K views/month, and each render takes 100ms of server time, that's 50,000 seconds of compute — roughly $25-100/month for content that's identical for every visitor. SSG costs pennies for the same traffic.
Common Mistakes
| What developers do | What they should do |
|---|---|
| Using one rendering strategy for every route because consistency seems simpler Different routes have fundamentally different requirements. A blog post and a user dashboard need different strategies. Modern frameworks support per-route configuration with zero extra complexity. | Choose per route based on data freshness, personalization, and SEO requirements |
| Defaulting to SSR because it handles every case SSR is the most expensive and slowest option for content that does not need it. Start with SSG, escalate to ISR if content changes, escalate to SSR only if content is personalized or must be real-time. | Default to the most static option that meets your requirements, then escalate to more dynamic strategies only when needed |
| Choosing a framework first, then fitting your rendering strategy to its strengths If 90% of your pages are static content and you choose a framework optimized for SPAs, you are fighting the framework. Let your content requirements drive the technology choice. | Define your rendering requirements per route first, then choose the framework that best supports that mix |
| Over-engineering with multiple frameworks (Astro for marketing, Next.js for app, Qwik for landing pages) Multiple frameworks mean multiple build pipelines, deployments, design systems, and team expertise requirements. The operational complexity usually outweighs the marginal performance gains. | Use one framework that supports hybrid rendering (like Next.js 15 or Astro) unless the performance difference is dramatic and measurable |
The Checklist
Before shipping any new page, answer these questions:
- Who sees this page? Same content for everyone, or personalized?
- How fresh must the data be? Real-time, minutes-old, or days-old acceptable?
- Does this page need SEO? Will search engines index it?
- How often does the content change? On publish, hourly, per request?
- What percentage is interactive? 5% (blog), 50% (dashboard), 95% (editor)?
- What are the performance targets? TTFB, LCP, TTI requirements?
- What is the traffic volume? 100 views/day or 100K views/day?
Map the answers to the decision tree. The strategy should be obvious.
Key Rules
- 1Default to the most static option that meets your requirements. SSG first, then ISR, then SSR, then CSR. Escalate only when the simpler strategy cannot satisfy your data freshness or personalization needs.
- 2Choose rendering strategy per route, not per application. Most production apps use 2-3 strategies across different routes.
- 3SSG and ISR are nearly free at scale (CDN-served static files). SSR cost scales linearly with traffic. Factor infrastructure cost into your architecture decisions.
- 4For partially personalized pages, keep the page static (SSG/ISR) and fetch personalized data client-side or use Server Components to stream just the personalized section.
- 5Streaming SSR (with Suspense boundaries) should be the default for any SSR page. There is no reason to block the entire response on the slowest data source.
- 6The best rendering strategy is the one your team can implement correctly. A well-executed ISR setup outperforms a poorly configured SSR + caching layer every time.