Setting up from the UK or Europe? Compare UAE free zones for 2026 in our setup guide.

Read the guide
Blog · App Development

React Rendering Patterns: CSR, SSR, SSG, and Modern Approaches

Cover: react-rendering-patterns-guide

React applications render in fundamentally different ways, and your choice of pattern affects performance, SEO, scalability, and development complexity. Client-side rendering (CSR) works well for interactive dashboards and real-time apps. Server-side rendering (SSR) improves Time to First Byte (TTFB) and search visibility. Static site generation (SSG) delivers the fastest initial load and requires minimal server resources. Modern React adds streaming, partial hydration, and Server Components to the picture, letting you combine benefits of each approach.

This guide walks you through each pattern, the performance tradeoffs you’re making, and the specific use cases where each shines. Along the way, you’ll see why a single “best” rendering strategy doesn’t exist and why most production apps use a hybrid approach.

Key Takeaways

  • CSR trades initial load speed for developer simplicity and interactivity; best for authenticated apps and dashboards where SEO doesn’t matter
  • SSR reduces Time to First Byte (TTFB) by ~40–60% and improves SEO, but increases server load and complexity
  • SSG provides the fastest Time to Interactive (TTI) and lowest server costs by pre-building at deploy time, ideal for content sites and marketing pages
  • ISR (Incremental Static Regeneration) allows static pages to update on demand without rebuilding the entire app
  • Streaming and partial hydration reduce Time to Interactive by sending HTML chunks to the browser before the full page is ready
  • Modern React Server Components allow you to fetch data and render directly on the server, eliminating waterfalls between client and server

Understanding Rendering Fundamentals

Custom React development ensures your application uses the optimal rendering pattern for performance and maintainability.

React gives you five core rendering strategies, each moving the work of converting components into HTML to different parts of your architecture. Understanding where that work happens is the key to choosing the right pattern.

Client-Side Rendering (CSR)

The browser downloads an empty HTML shell and JavaScript bundle, then renders the entire page in the browser. React hydrates the DOM and attaches event listeners. This is how React started, and it’s still the default for Create React App.

Server-Side Rendering (SSR)

React renders on the server during each request, sending a fully formed HTML page to the browser. The browser receives and displays the content immediately, then React hydrates to add interactivity.

Static Site Generation (SSG)

React renders your pages at build time, producing plain HTML files. These files are served from a CDN with no server processing needed. The build happens once, and pages are reused across every user request.

Incremental Static Regeneration (ISR)

A hybrid between SSG and SSR: pages are pre-built at deploy time, but you can mark them for revalidation. When a user requests a page after its revalidation period expires, the server re-renders it in the background and replaces the cached version.

Streaming and Progressive Enhancement

React 18 added Suspense for SSR, letting you send HTML in chunks. The server streams the page to the browser in pieces rather than waiting for the entire page to be ready, reducing Time to Interactive by sending interactive parts first.

Client-Side Rendering: When Interactivity Comes First

CSR is the simplest pattern from an infrastructure perspective: build your app, upload the bundle to a CDN, and you’re done. The tradeoff is performance. Users wait for the JavaScript to download, parse, and execute before they see anything meaningful on screen.

Performance Characteristics

A typical CSR app has a Time to First Byte (TTFB) of 100-300ms, but Time to Interactive (TTI) of 3-8 seconds on average mobile connections after accounting for JavaScript download and parsing. Initial bundle size is often 200-500KB for a medium-sized app. This is because all rendering logic lives in JavaScript.

Caching is simple: set a long cache TTL on your JavaScript bundles using content hashing, and CDNs serve the files globally with sub-second latency. SEO is a problem, however. Search engines struggle with JavaScript-heavy apps, and even with server-side rendering from headless browsers, crawling is slower and less reliable than serving static HTML.

When CSR Works Well

Use CSR for user dashboards, project management tools, collaborative editors, and apps where most users are authenticated and SEO is not a priority. CSR is also the right choice when your app relies on real-time data from an API and pages refresh frequently enough that pre-rendering becomes impractical.

Example: A project management app like Jira or Asana uses CSR because every team’s workspace is unique, most users are logged in, and the page updates constantly. Pre-rendering every possible view would be wasteful.

Reducing CSR Pain Points

If you’re using CSR, reduce the bundle size by code splitting at route boundaries. Use dynamic imports to load features only when users navigate to them. Implement a loading skeleton or placeholder while JavaScript loads. Pre-connect to critical API endpoints in your HTML head. These practices reduce the perceived wait time significantly.

bundle-optimization-and-code-splitting

Server-Side Rendering: Fast First Paint at the Cost of Complexity

For production web application architecture, rendering pattern selection is critical to user experience and server costs.

SSR renders React on the server during each request and sends fully-formed HTML to the browser. The browser paints the page immediately while JavaScript is still downloading. Users see content fast, but the server has to do work for every visitor.

The SSR Advantage: TTFB and SEO

SSR reduces Time to First Byte by 40–60% compared to CSR because the server sends rendered HTML instead of an empty shell. Crawlers receive complete HTML immediately, making SSR the standard for content-heavy sites and marketing pages that need search visibility.

SSR also enables personalization: you can inspect the user’s cookies or headers on the server and render different content for different users without a network round-trip. This is critical for e-commerce sites where product availability or pricing varies by region.

The SSR Cost: Server Load and Latency

Every request triggers a React render on the server. If you have 100 concurrent users, your server is rendering 100 pages simultaneously. This requires more compute than serving pre-built files. Latency is also higher because the server has to wait for data fetches, template renders, and sometimes downstream API calls before responding.

Databases can become a bottleneck. If your render process queries a database, traffic spikes hit your database, your app server. This is why SSR apps almost always cache responses at the CDN level using cache headers.

Implementing SSR Effectively

Use a framework that abstracts the complexity. Next.js App Router and Remix both handle SSR setup, streaming, and data fetching. Avoid building SSR from scratch with Express and ReactDOMServer unless you have a very simple use case.

Always use caching headers. Set Cache-Control to revalidate after 30 seconds or 1 minute for pages that update regularly. This reduces server load dramatically. Use HTTP caching headers and CDN edge caching to move rendering closer to users.

production-react-architecture

Static Site Generation: The Performance Winner

SSG pre-renders pages at build time and serves them from a CDN. No server processing happens when users visit your site. This is the fastest pattern for pages that don’t need personalization or real-time data.

Performance and Cost Benefits

SSG achieves the best Time to Interactive on any pattern: typically 0.5–1.5 seconds on mobile. Pages are pure HTML and CSS with minimal JavaScript, so the browser parses and paints instantly. Bandwidth usage is low because you’re serving static files.

Server costs are nearly zero. A CDN serves all requests without hitting your origin. You pay for the build process once per deploy, then CDN egress for the file transfers. This makes SSG ideal for high-traffic sites where per-request costs add up quickly.

The SSG Constraint: Static Content

SSG only works when you can know all the pages you need to build ahead of time. A product catalog with 10,000 SKUs is fine; you generate a page for each product at build time. A personalized dashboard is not; you can’t pre-render every possible view.

If your content updates frequently, you’ll either rebuild your entire site often (expensive and slow) or accept stale data. This is where Incremental Static Regeneration (ISR) enters the picture.

ISR: Static Generation That Updates

ISR lets you mark pages for revalidation. When a user requests an SSG page after its revalidation time has passed, the server re-renders the page in the background and caches the new version for subsequent requests. This combines the speed of static files with the freshness of server-rendering.

Example: A blog can use ISR with a 60-second revalidation time. After deploying a new post, the first user to visit the blog will see the new post generated on-demand. The next visitors see the cached version until the revalidation period expires again.

When to Use SSG and ISR

Use SSG for marketing sites, blogs, documentation, landing pages, and any content that doesn’t change between requests. Use ISR when your content updates occasionally but not constantly, like a product catalog that gets new items daily or a news site with hourly updates.

Hybrid Approaches: Combining Patterns in Production Apps

Most production React apps don’t use a single pattern across the entire site. Instead, they mix patterns to optimize for specific pages and user flows.

SSG Plus Client-Side Interactivity

Pre-build your page as static HTML, then attach interactive features on the client. This is ideal for marketing pages: the landing page is pure SSG for performance, but a contact form or pricing calculator hydrates on the client.

Next.js makes this easy. You can generate a static page with next/image and next/link, then import a React component to handle form submission or filtering without re-rendering the entire page on the server.

SSR with CDN Caching

Render on the server but cache the response at the CDN level. This gives you personalization (via server-side logic) with CDN speeds (via edge caching). Set Cache-Control headers based on content freshness: 30 seconds for user-dependent pages, 1 hour for mostly-static content.

Cloudflare and Vercel edge networks excel at this. The edge location closest to the user caches the rendered response, so the server only re-renders when the cache expires.

Route-Level Pattern Selection

Different routes can use different patterns. Your homepage is SSG. Your blog post pages are SSG with ISR. Your product pages are SSR with aggressive caching. Your user dashboard is pure CSR because it’s personalized and updates frequently. This granular approach gives you the best tradeoff for each page type.

Modern React Patterns: Server Components and Streaming

React 18 and beyond introduced streaming and the concept of Server Components, shifting how we think about client-server boundaries.

Streaming HTML with Suspense

React 18’s Suspense for SSR lets you send the page in chunks. The server sends the layout and high-priority content immediately, then streams additional sections as they’re ready. The browser renders and displays content as it arrives, reducing perceived load time.

This is especially powerful for pages with secondary content: a news article streams the headline and first few paragraphs immediately, then streams related articles, comments, and recommendations as they’re fetched.

React Server Components

Server Components run only on the server and don’t ship JavaScript to the browser. They can fetch data, access databases, and read environment variables directly. Client Components hydrate interactivity as needed. This eliminates the data-fetching waterfall: instead of fetching on the client, waiting for a response, then rendering, the server fetches and renders together.

The tradeoff is complexity. Server Components require a framework that understands the server/client boundary, like Next.js 13+ or Remix. You can’t use browser APIs in Server Components, and serialization rules are strict.

Partial Hydration and Progressive Enhancement

Not every component needs interactivity. Modern frameworks let you mark components as interactive (Client Components) while keeping the rest static. This reduces JavaScript shipped to the browser and improves TTI.

The principle is progressive enhancement: send interactive HTML and CSS first, then enhance with JavaScript only where needed. This makes your app resilient if JavaScript fails to load.

Choosing Your Rendering Pattern: A Decision Framework

Use this framework to decide which pattern fits your project.

Does SEO matter? If yes, you need server-rendered HTML. SSG or SSR, depending on whether content is dynamic. If no, CSR is simpler.

Is content personalized per user? If yes, SSR or streaming is required. If no, SSG works fine.

Do you need real-time updates? If yes, CSR or streaming is necessary. ISR works for hourly or daily updates. If no, SSG is the fastest option.

How much traffic? High traffic favors SSG and CDN caching to reduce server load. Low traffic can support SSR without infrastructure strain.

Do you have complex data dependencies? Streaming and Server Components reduce complexity by fetching and rendering together. Waterfall chains (client fetches, then renders, then fetches again) are eliminated.

Conclusion: Match the Pattern to Your Use Case

React rendering patterns are tools, not destinations. CSR is simple but slow. SSR is flexible but complex. SSG is fastest but static. Modern streaming and Server Components let you combine benefits, but they require newer frameworks and more careful architecture.

The best rendering strategy for your app depends on your specific audience, content freshness requirements, and SEO needs. A blog needs SSG or SSR. A dashboard needs CSR. A SaaS marketing site benefits from SSR or SSG combined with edge caching.

If you’re building a custom React application and need help deciding on the right rendering architecture for your performance and SEO goals, Codeeo’s React development team works with teams to design rendering strategies that match your scale and user experience requirements. codeeo-custom-software-development

Questions readers ask

Which rendering pattern is best for a SaaS application?

Most SaaS dashboards use CSR because content is personalized, users are authenticated, and SEO is not required. Combine this with a GraphQL or REST API for data fetching. If you have public marketing pages, use SSG or SSR for those routes separately and CSR for the dashboard.

Does SSR hurt SEO if I use CSR for my main app?

No. Use SSR or SSG for your marketing site and public content. Use CSR for logged-in features. Search engines crawl the public pages and ignore the CSR routes behind authentication.

Can I migrate an existing CSR app to SSR?

Yes, but it requires refactoring. Move data fetching from useEffect to server code. Handle environment variables and secrets on the server instead of the client. Test that hydration matches between server and client render. Use a framework like Next.js to automate much of this.

What's the performance impact of hydration mismatch?

Hydration mismatch causes React to discard the server-rendered HTML and re-render on the client, losing the benefit of server-side rendering. TTFB improves, but TTI doesn't. Common causes: random values (Math.random, dates), browser APIs used in render, CSS-in-JS mismatches. Prevent this by avoiding non-deterministic logic in your render functions.

Is ISR right for my content site?

ISR is best for content that updates occasionally: news sites (hourly), product catalogs (daily), documentation (weekly). For content that changes constantly (chat apps, real-time dashboards), streaming or CSR is better. ISR requires you to know when content will be stale; if updates are unpredictable, use on-demand revalidation (available in Next.js 13+).

How does streaming affect Time to Interactive?

Streaming reduces TTI by sending HTML to the browser in chunks rather than waiting for the entire page to be rendered on the server. The browser can start parsing and rendering the layout while the server is still rendering secondary content. On average, TTI improves by 20u201340% depending on how well you structure your Suspense boundaries.

Keep reading

Want this done for your company?

Tell us what you are launching and we will come back with a written quote.

Get a free quote