← All posts
7 min read

Server-Side Rendering and Client-Side Rendering: Where Web Interfaces Take Shape

#technology#server-side-rendering#client-side-rendering#web-development
📑 On this page

A browser ultimately needs HTML and related resources to present a page.

The question is where and when that HTML is produced.

Server-side rendering creates the initial page representation on a server; client-side rendering constructs more of the interface in the browser using JavaScript.

Modern applications often combine both, choosing per route and interaction rather than declaring one universal winner.

A concrete example: a product page

A user requests /products/shoe-a7.

With server-side rendering:

  1. The server receives the request.
  2. It reads product data.
  3. It generates HTML containing name, price, and description.
  4. The browser can display content.
  5. JavaScript loads and adds interaction.

With client-side rendering:

  1. The server returns a mostly generic application shell.
  2. JavaScript loads.
  3. Browser code requests product data.
  4. The browser builds the product interface.

Both can produce the same final screen, but the loading path differs.

The browser always renders pixels

The terms can be confusing.

Even with server-side rendering, the browser:

  • Parses HTML
  • Applies CSS
  • Builds layout
  • Paints pixels
  • Executes JavaScript

Server rendering means the server produced an initial HTML representation.

Client rendering means browser JavaScript creates or changes more of that representation.

The distinction is about where application rendering logic runs, not where the screen physically appears.

Server-side rendering

SSR can provide:

  • Useful HTML on first response
  • Faster visible content on some devices and networks
  • Better support when JavaScript is delayed
  • Straightforward metadata for sharing and search
  • Server-controlled data access

Costs include:

  • Server computation for requests
  • Time waiting for server data
  • More complex caching with personalization
  • Hydration work in browser
  • Coordination between server and client code

SSR quality depends on the whole path, not the label.

Client-side rendering

CSR can provide:

  • Rich transitions after initial load
  • Browser-resident application state
  • Reduced server HTML generation
  • App-like interaction
  • Clear separation behind APIs

Costs include:

  • More JavaScript download and execution
  • Blank or incomplete initial states
  • Extra data round trips
  • Greater device burden
  • Routing, state, and error complexity

On a powerful laptop with a warm cache, CSR may feel instant. On a low-powered phone with slow network, the same bundle can delay content significantly.

Hydration

Server-rendered HTML is initially static markup.

Hydration loads client JavaScript and attaches behavior:

  • Event handlers
  • State
  • Interactive components
  • Client routing

The client render must match the server output closely.

Differences can cause hydration warnings, discarded markup, or visible movement.

Common mismatch sources include:

  • Current time
  • Random values
  • Browser-only state
  • Locale differences
  • Data changing between renders

Treat server and client rendering as two executions that need deterministic agreement.

Progressive enhancement

Progressive enhancement begins with functional HTML and adds richer behavior when browser capabilities are available.

A form can submit normally, then JavaScript enhances it with inline validation and optimistic feedback.

Benefits:

  • Resilience
  • Accessibility
  • Faster basic interaction
  • Simpler failure fallback

Not every complex tool can function fully without JavaScript.

The principle remains useful: essential workflows should not become unnecessarily dependent on decorative client code.

Static generation

Static generation creates HTML before a request, often during build or background regeneration.

It fits:

  • Documentation
  • Marketing pages
  • Blog posts
  • Product pages with manageable freshness

Static files can be cached globally with low server cost.

Challenges include:

  • Build time
  • Freshness
  • Large page counts
  • Personalization

Incremental regeneration and on-demand invalidation combine static delivery with controlled updates.

Static generation is server-side production at an earlier time.

Streaming server rendering

A server can stream HTML in pieces.

The page shell and fast content arrive while slower sections continue loading.

Streaming can improve perceived speed and avoid waiting for every backend dependency before sending anything.

It requires:

  • Meaningful loading boundaries
  • Stable layout
  • Error handling per section
  • Careful caching

Streaming slow content without prioritization can create a page that shifts and distracts.

The user experience should communicate which parts are ready.

Server components and split execution

Some frameworks let components execute only on the server while sending rendered output and selected data to the browser.

Benefits can include:

  • Less client JavaScript
  • Direct server data access
  • Server-only secrets
  • Component composition

Interactive components still run in the browser.

The boundary affects:

  • Serialization
  • State
  • Bundling
  • Data freshness
  • Testing

Framework terminology varies. Understand which code runs where and what crosses the boundary.

Caching server-rendered output

SSR does not mean every request must regenerate everything.

Caches can store:

  • Full HTML
  • Data queries
  • Component fragments
  • Generated assets

Public pages can use CDN caching.

Personalized output needs private or carefully keyed caching.

Never cache one user's sensitive page as a public response.

Cache keys, cookies, authorization, and Vary behavior are part of rendering architecture.

Personalization

Personalized pages complicate server caching.

Options include:

  • Render common public shell on server.
  • Fetch private data after load.
  • Use edge personalization with strict keys.
  • Render per user with private caching.
  • Personalize only selected islands.

Do not make the entire page uncacheable because one small greeting differs.

Separate shared and private concerns.

Privacy also matters: personalized HTML can appear in logs or intermediary caches if headers are wrong.

An SSR application can use client-side navigation after hydration.

When a user selects another route:

  • Browser may fetch data or server-rendered fragments.
  • Existing layout remains.
  • History updates.
  • Focus and title need management.

This produces hybrid navigation.

Client routing should preserve:

  • Back and forward behavior
  • Deep links
  • Scroll and focus
  • Loading states
  • Error recovery

Fast transitions are not useful if browser expectations break.

Search crawlers and social-preview systems need discoverable content and metadata.

Server or static rendering provides those values immediately.

Many crawlers execute JavaScript, but behavior, timing, and resource budgets vary.

For public content:

  • Use meaningful URLs.
  • Return correct status codes.
  • Provide canonical metadata.
  • Ensure content exists without user-specific execution.

SEO is not a reason to server-render every private dashboard. Match rendering to audience and discoverability.

Performance has several stages

Measure:

  • Server response time
  • HTML arrival
  • Visible content
  • JavaScript download
  • Hydration
  • Interaction readiness
  • Navigation latency

SSR can display content early while main-thread hydration blocks interaction.

CSR can return a fast shell but delay useful content.

One metric cannot tell the whole story.

Use real-user data across devices and networks.

Failure behavior

Ask:

  • What if JavaScript fails?
  • What if one data source is slow?
  • What if hydration errors?
  • What if client navigation loses network?
  • What if cached HTML is stale?

Server rendering can provide a readable fallback.

Client rendering can preserve already-loaded state during a backend interruption.

Design loading, timeout, retry, and partial content explicitly.

Rendering architecture is also failure architecture.

Security boundaries

Code running in the browser is visible and modifiable.

Keep:

  • Secrets
  • Trusted authorization
  • Private data access
  • Final business validation

on controlled servers.

Server rendering can embed only data the current user is authorized to receive.

Avoid serializing whole server objects into the page when only a few fields are needed.

Rendering location does not change the rule that client input is untrusted.

Choosing per experience

Server or static rendering often fits:

  • Public content
  • Product detail
  • First-load-critical pages
  • Shareable URLs

Client rendering often fits:

  • Highly interactive tools
  • Complex authenticated dashboards
  • Local-first behavior
  • Long sessions after initial load

Hybrid approaches fit many products.

Choose at the route or component level from content, interaction, device cost, caching, privacy, and failure needs.

Knowledge check

  1. What does server-side rendering actually move to the server?
  2. What is hydration?
  3. How does static generation differ in timing from request-time SSR?
  4. Why can personalized SSR be dangerous to cache?
  5. Which stages should performance measurement include beyond server response?

The one idea to remember

Rendering location is a per-experience tradeoff. Use server, static, client, and streaming techniques to balance first content, interaction, device work, caching, personalization, and resilience rather than choose one ideology for every page.