Rendering & Data Architecture
(How frontend systems actually move data and pixels)
Architect rule:
Rendering and data flow are not implementation details.
They are core architectural decisions.
Chapter 1 — The Rendering Spectrum (Not a Binary Choice)
1.1 The False CSR vs SSR Debate
Most discussions frame rendering as:
-
Client-Side Rendering (CSR)
-
Server-Side Rendering (SSR)
This is architecturally wrong.
Modern frontend rendering exists on a spectrum, not a switch.
1.2 The Full Rendering Matrix
Model
What It Is
Architect Use Case
CSR
HTML shell + JS renders UI
Highly interactive apps, low SEO
SSR
Server renders HTML per request
SEO-critical, fast first paint
SSG
HTML generated at build time
Marketing pages, docs
ISR
Incremental regeneration
Semi-dynamic content
Streaming SSR
HTML streamed in chunks
Large pages, progressive UX
Partial Hydration
Hydrate only interactive parts
Performance-sensitive pages
Architect insight:
A single application may use all of these simultaneously.
1.3 Rendering Is a Cost Model
Every rendering mode has cost dimensions:
-
Compute cost (server vs client)
-
Network cost
-
Hydration cost
-
Operational complexity
-
Caching complexity
Architects price these costs explicitly before choosing.
Chapter 2 — Choosing Rendering Strategy (Decision Framework)
2.1 Architect Questions (Always Ask These)
Before choosing a rendering mode, answer:
-
Is SEO critical for this route?
-
What must be interactive immediately?
-
What data is required to render above-the-fold?
-
How frequently does this data change?
-
Who pays the compute cost — client or server?
If you cannot answer all five, you are guessing.
2.2 Route-Level Rendering Decisions
Architect rule
Rendering strategy is chosen per route, not per app.
Example:
Route
Strategy
Why
Landing page
SSG
Fast, cacheable
Auth pages
SSR
SEO + correctness
Dashboard
CSR + data streaming
Highly interactive
Admin reports
SSR + caching
Data-heavy
This avoids the “one-size-fits-none” problem.
2.3 The Hidden Cost of Hydration
Hydration:
-
replays component trees
-
attaches event handlers
-
blocks the main thread
Architect takeaway
SSR without hydration strategy is often worse than CSR.
This is why:
-
partial hydration
-
server components
-
island architectures exist
Chapter 3 — Server Components & Client Components (Architect View)
3.1 What Server Components Actually Are
Forget the hype.
Server Components mean:
-
code that runs only on the server
-
zero JS shipped to client
-
access to backend resources directly
They are a data access and rendering boundary, not a UI trick.
3.2 Architect Benefits
Server Components allow architects to:
-
move data fetching to server
-
reduce client bundle size
-
eliminate duplicated API logic
-
enforce security boundaries
This is architectural leverage, not syntactic sugar.
3.3 The New Boundary: Data vs Interaction
Architects now draw a clear line:
-
Server Components → data assembly, layout, composition
-
Client Components → interactivity, local state, gestures
Architect rule:
Interaction stays client-side.
Data orchestration moves server-side.
3.4 Common Anti-Patterns
Avoid:
-
making everything a client component
-
passing large serialized data trees
-
embedding business logic in UI components
These negate the architectural benefits.
Chapter 4 — Data Architecture: Ownership Before Tools
4.1 The Core Data Question
Every piece of data must answer:
Who owns this data, and where is the source of truth?
Architects design data ownership maps before choosing libraries.
4.2 The Four Data Domains (Revisited, Deeper)
1. Server-Owned Data
-
authoritative source
-
persisted
-
cached aggressively
Examples:
-
user profile
-
orders
-
permissions
Architect rule:
This data should never be duplicated as client state.
2. Client UI State
-
ephemeral
-
local
-
non-persistent
Examples:
-
modal visibility
-
tab selection
Architect rule:
Keep it local. Never globalize UI state.
3. URL State
-
shareable
-
navigable
-
durable
Examples:
-
filters
-
pagination
-
search
Architect rule:
If users expect “back” to work, it belongs in the URL.
4. Global Client State
-
cross-cutting
-
rare
-
dangerous if abused
Examples:
-
auth session
-
feature flags
-
theme
Architect rule:
Global state is a last resort.
Chapter 5 — Caching as Architecture
5.1 Cache Is Not an Optimization
Cache is:
-
a contract
-
a consistency decision
-
a staleness agreement
Architects decide:
-
acceptable staleness
-
invalidation rules
-
refresh triggers
5.2 Multi-Layer Cache Model
CDNCache
↓
Browser HTTPCache
↓
FrameworkCache
↓
In-MemoryCache
Each layer has:
-
different lifetime
-
different invalidation cost
-
different ownership
Architects define which layer owns freshness.
5.3 Cache Invalidation Strategies
Architect-approved patterns:
-
Time-based revalidation
-
Event-based invalidation
-
User-triggered refresh
-
Background re-fetch
Anti-pattern:
“Just refetch everything.”
Chapter 6 — Data Fetching Patterns (Architect Level)
6.1 Request Waterfalls Are Architectural Failures
If rendering requires:
-
fetch A
-
then fetch B
-
then fetch C
You have a data architecture problem, not a React problem.
Architects fix this by:
-
backend aggregation
-
parallel fetching
-
server-side orchestration
6.2 BFF (Backend-for-Frontend) Pattern
Architects often introduce:
-
a frontend-specific backend
-
optimized for UI needs
-
stable contracts
This:
-
reduces client complexity
-
improves performance
-
decouples frontend from backend churn
6.3 Error Handling as Data Architecture
Errors are also data.
Architects define:
-
error taxonomy
-
retry rules
-
user-visible vs silent failures
This prevents:
-
random toasts
-
inconsistent UX
-
debugging nightmares
Chapter 7 — State Synchronization & Consistency
7.1 The Illusion of “Single Source of Truth”
In distributed systems (frontend + backend):
-
perfect consistency is impossible
-
latency exists
-
failures happen
Architects design for eventual consistency.
7.2 Optimistic vs Pessimistic Updates
Strategy
When to Use
Optimistic
Fast UX, reversible actions
Pessimistic
Critical data, high risk
Architects decide this per action, not globally.
7.3 Synchronization Rules
Architect-level rules:
-
mutations update server first
-
caches invalidate predictably
-
UI reflects uncertainty clearly
Chapter 8 — Anti-Patterns Architects Eliminate
🚫 Global state mirroring server data
🚫 Fetching data inside deep UI components
🚫 Rendering logic tied to API shape
🚫 Inconsistent cache lifetimes
🚫 SSR everywhere “just in case”
These are structural failures, not code smells.
Chapter 9 — Exercises (Critical)
Exercise 1 — Route Rendering Matrix
Pick your current app.
For each route, define:
-
rendering mode
-
data sources
-
cache strategy
If you can’t justify each choice, refactor.
Exercise 2 — Data Ownership Map
Draw:
-
all major data entities
-
who owns them
-
where they are cached
-
how they invalidate
This alone will surface hidden complexity.
Exercise 3 — Hydration Cost Audit
List:
-
interactive components
-
when they hydrate
-
what blocks the main thread
Architects reduce hydration, not just bundle size.
Chapter 10 — Part III Summary
After Part III, you should:
-
Treat rendering as a design decision
-
Choose strategies per route
-
Separate data orchestration from interaction
-
Design caching deliberately
-
Prevent waterfalls by architecture
If Part II taught you how browsers work,