ESC
Type to search guides, tutorials, and reference documentation.
Verified by Garnet Grid

Server-Side Rendering Strategies

Choose and implement the right rendering strategy for performance and SEO. Covers SSR, SSG, ISR, streaming SSR, edge rendering, hydration patterns, and the patterns that deliver fast, SEO-friendly web applications.

How and where your HTML is rendered determines your page load speed, SEO ranking, and user experience. The wrong rendering strategy can mean a 3-second blank page (bad CSR), stale content (bad SSG), or expensive compute (bad SSR). Choosing the right strategy per page is the key to performance.


Rendering Strategies Compared

Client-Side Rendering (CSR):
  Where: Browser
  When: On every page load
  HTML: Empty shell, JS builds the page
  
  First Paint: Slow (download JS → execute → render)
  SEO: Poor (search engines may not execute JS)
  Server Cost: Low (serve static files)
  Best for: Dashboards, admin panels, authenticated pages

Server-Side Rendering (SSR):
  Where: Server
  When: On every request
  HTML: Complete HTML sent to browser
  
  First Paint: Fast (HTML arrives ready)
  SEO: Excellent (full HTML for crawlers)
  Server Cost: High (render per request)
  Best for: Dynamic content that changes per user/request

Static Site Generation (SSG):
  Where: Build server
  When: At build time
  HTML: Pre-built HTML files
  
  First Paint: Fastest (serve pre-built files from CDN)
  SEO: Excellent (full HTML)
  Server Cost: Lowest (no compute at request time)
  Best for: Blogs, docs, marketing pages, content that rarely changes

Incremental Static Regeneration (ISR):
  Where: Edge / Server
  When: On first request after revalidation period
  HTML: Pre-built, regenerated in background
  
  First Paint: Fast (serve stale, regenerate in background)
  SEO: Excellent
  Server Cost: Low (regenerate only when stale)
  Best for: Product pages, blog posts, content that changes periodically

Streaming SSR

// Next.js App Router: Streaming SSR with Suspense
// Server sends HTML in chunks as data becomes available

// app/dashboard/page.tsx
import { Suspense } from 'react';

export default function DashboardPage() {
  return (
    <div>
      {/* Header renders immediately */}
      <h1>Dashboard</h1>
      
      {/* Revenue streams in when data is ready */}
      <Suspense fallback={<RevenueSkeleton />}>
        <RevenueChart />  {/* Server component - fetches data */}
      </Suspense>
      
      {/* Orders stream independently */}
      <Suspense fallback={<OrdersSkeleton />}>
        <RecentOrders />  {/* Another server component */}
      </Suspense>
    </div>
  );
}

// Server Component: Fetches data on server, streams HTML when ready
async function RevenueChart() {
  const data = await fetchRevenueData();  // Slow API call (2 seconds)
  
  return (
    <div className="chart">
      {data.map(point => (
        <Bar key={point.month} value={point.revenue} />
      ))}
    </div>
  );
}

// Timeline:
// 0ms:   Shell HTML sent (header + skeletons)
// 200ms: Orders data ready → HTML chunk streamed
// 2000ms: Revenue data ready → HTML chunk streamed
// 
// Without streaming: User waits 2000ms for anything
// With streaming: User sees layout immediately, data fills in

Per-Page Strategy

Page Type            | Strategy | Revalidation
---------------------|----------|-------------
Homepage             | ISR      | Every 60 seconds
Blog post            | SSG      | On content change (webhook)
Product page         | ISR      | Every 5 minutes
Search results       | SSR      | Every request
User dashboard       | CSR      | Client-side
Checkout flow        | SSR      | Every request (no caching)
API documentation    | SSG      | On deploy
Pricing page         | SSG      | On deploy

Anti-Patterns

Anti-PatternConsequenceFix
CSR for SEO-critical pagesPoor search rankingsSSR or SSG for public pages
SSR for static contentUnnecessary compute costSSG or ISR for content pages
No loading skeletonsLayout shift, poor UXSuspense boundaries with skeletons
Full page SSR (no streaming)Slowest component blocks entire pageStreaming SSR with Suspense
SSG with frequent rebuildsLong build times, stale contentISR for frequently changing content

The best applications use different rendering strategies for different pages. A blog post does not need SSR. A dashboard does not need SSG. Match the strategy to the page.

Jakub Dimitri Rezayev
Jakub Dimitri Rezayev
Founder & Chief Architect • Garnet Grid Consulting

Jakub holds an M.S. in Customer Intelligence & Analytics and a B.S. in Finance & Computer Science from Pace University. With deep expertise spanning D365 F&O, Azure, Power BI, and AI/ML systems, he architects enterprise solutions that bridge legacy systems and modern technology — and has led multi-million dollar ERP implementations for Fortune 500 supply chains.

View Full Profile →