Rendering
How to choose the right rendering architecture for your web project. See the Tech Stack section for our recommended frameworks and tools.
Rendering Strategiesβ
Modern web applications sit on a spectrum between fully client-rendered and fully server-rendered. Each strategy makes different trade-offs between performance, SEO, interactivity, and infrastructure complexity. Understanding these trade-offs helps you pick the right approach β or the right combination β for your project.
Client-Side Rendering (SPA)β
The server sends a minimal HTML shell along with a JavaScript bundle. The browser downloads and executes that JS, fetches data from APIs, and renders the entire UI on the client.
- Fast post-load navigation β once the app is loaded, route transitions are instant with no server round-trips.
- Simple hosting β the output is a set of static files that can be served from any CDN or static host at low cost.
- Rich interactivity β the entire application state lives in the browser, making complex UI interactions straightforward.
- Slow First Contentful Paint (FCP) β the user sees nothing meaningful until the JS bundle has been downloaded, parsed, and executed.
- Large bundles hurt Time to Interactive (TTI) β as the app grows, so does the JS payload, pushing interactivity further out.
- SEO challenges β search-engine bots that don't execute JavaScript may not index your content correctly.
Best for: internal tools, dashboards, admin panels, and apps behind authentication where SEO doesn't matter.
Further reading: Client-Side Rendering β patterns.dev
Server-Side Rendering (SSR)β
The server generates full HTML for every request. The browser paints the page immediately, then hydrates it with JavaScript to restore interactivity.
- Fast FCP β users see meaningful content as soon as the HTML arrives, without waiting for JS execution.
- Excellent SEO β crawlers receive complete HTML, so all content is indexable out of the box.
- No client-side data-fetch waterfalls β the server can resolve all data dependencies before sending the response.
- Higher Time to First Byte (TTFB) β the server must compute each page on every request, adding latency.
- Hydration cost β the page looks ready but isn't interactive until JS loads and hydrates, creating an "uncanny valley" for users.
- More complex infrastructure β requires a running server and careful caching strategies compared to static hosting.
Best for: content sites that need SEO combined with dynamic or personalized data, such as e-commerce product pages or user-specific feeds.
Frameworks like Next.js, Remix, and Astro all support SSR. See the Tech Stack for our specific recommendations.
Further reading: Server-Side Rendering β patterns.dev
Static Site Generation (SSG)β
Pages are pre-rendered at build time and served as static files from a CDN. No server-side computation happens at request time.
- Fastest TTFB β pre-built files are served directly from edge caches with no server processing.
- Excellent SEO β fully rendered HTML is ready for crawlers from the first byte.
- Lowest infrastructure cost β static hosting is cheap: no application servers, no scaling concerns.
- Maximum reliability and cacheability β every response is the same static file, making caching trivial.
- Content only updates on rebuild β changes require a new build and deploy cycle.
- Build times scale with page count β large sites can face long build durations.
Best for: blogs, documentation sites, marketing pages, and landing pages.
Further reading: Static Rendering β patterns.dev
Islands Architectureβ
The page is delivered as static HTML with selectively hydrated interactive "islands." Most of the page ships zero JavaScript; only explicitly marked components download and hydrate their own JS.
- Near-zero JS by default β pages are fast and lightweight unless you opt individual components into interactivity.
- Independent, parallel hydration β each island loads and hydrates on its own, so one slow component doesn't block the rest.
- Framework flexibility β different islands can use different UI frameworks on the same page.
- Less suited for SPA-like apps β if nearly every component is interactive, the islands model adds overhead without clear benefit.
- Inter-island state sharing β communicating between islands requires explicit patterns (events, shared stores) rather than a single component tree.
Best for: content-heavy sites with pockets of interactivity β marketing sites, docs with interactive demos, e-commerce storefronts.
Astro is our recommended framework for this pattern.
Further reading: Islands Architecture β patterns.dev
Comparisonβ
| Dimension | CSR (SPA) | SSR | SSG | Islands |
|---|---|---|---|---|
| TTFB | Fast (static shell) | Slower (server compute) | Fastest (CDN) | FastβFastest |
| FCP | Slow (JS must execute) | Fast (HTML in response) | Fastest | FastβFastest |
| TTI | Slow (large bundle) | Moderate (hydration) | Fast (minimal JS) | Fast (minimal JS) |
| SEO | Challenging | Excellent | Excellent | Excellent |
| Dynamic content | Excellent | Excellent | Poor | Good (server islands) |
| Hosting cost | Low (static host) | MediumβHigh (server) | Lowest (CDN) | LowβMedium |
| Caching | Easy (static assets) | Complex (per-request) | Trivial | Mostly trivial |
Real-world performance depends heavily on implementation quality, bundle size, and infrastructure β these are directional guidelines, not guarantees.
For definitions of FCP, TTFB, LCP, and how to measure them, see Performance & Core Web Vitals.
How to Chooseβ
Start with the simplest option that meets your requirements, then scale up complexity only when needed.
- Default to SSG for content sites, docs, blogs, and marketing pages β it's the fastest and cheapest option.
- Use Islands (Astro) when you need selective interactivity on an otherwise static site β this is our recommended default for new content-focused projects. See Astro.
- Choose SSR when pages require per-request personalization, real-time data, or user-specific content that can't be pre-built.
- Use CSR (SPA) for highly interactive applications like dashboards or admin panels where SEO is not a concern.
Modern frameworks let you combine strategies within a single project. Start static and upgrade individual routes to SSR or client-side rendering as requirements demand.
Emerging Patternsβ
The rendering landscape continues to evolve. Keep these patterns on your radar:
- Streaming SSR β the server sends HTML in chunks as data resolves, reducing perceived load time.
- React Server Components (RSC) β a component-level server/client boundary where only interactive components ship JavaScript to the browser.
- Incremental Static Regeneration (ISR) β individual pages rebuild on demand without requiring a full site rebuild.
- Edge rendering β SSR logic runs at CDN edge nodes, cutting latency by moving compute closer to users.
- Partial prerendering β combines a static shell with dynamically streamed content in a single response.
These trends are converging toward per-component rendering decisions rather than app-wide strategy choices.
Project Recipesβ
For practical implementations of these rendering strategies, see the project cookbooks:
- React SPA on Cloud Run β client-side rendered CRUD application with REST API
- React SPA with Firebase β client-side rendered app with Firebase BaaS
- Astro Starlight on GitHub Pages β static documentation site with SSG