Evolution of Frontend Rendering Modes: CSR, SSR, SSG, ISG, Progressive Hydration and Islands Architecture
This article traces a decade of front‑end rendering evolution, explaining traditional server‑side rendering, the rise of client‑side frameworks, modern hybrid approaches such as SSR, SSG, ISG, progressive and selective hydration, streaming SSR, islands architecture and React Server Components, while highlighting their trade‑offs and use‑cases.
React has been released for ten years, and the author reflects on a decade of front‑end development, crediting the Head First series for making programming approachable.
CSR – Client‑Side Rendering
In CSR the browser renders the page, while the server only serves static assets. The initial HTML is an empty shell, and the page becomes interactive only after the JavaScript bundle loads, leading to a long white‑screen period.
Advantages: simple deployment, smooth page transitions, suitable for complex interactive apps.
Disadvantages: poor SEO, long white‑screen time, potentially complex state management.
SSR – Server‑Side Rendering
SSR moves data fetching to the server, reducing TTFB compared to CSR, but still requires the client bundle for hydration. The server sends initial HTML and data, then the browser re‑renders (hydration) to make the DOM interactive.
Advantages: SEO‑friendly, users see content faster.
Disadvantages: requires a Node.js runtime, still ships the full client bundle, TTI can still be high.
SSG – Static Site Generation
SSG pre‑renders pages at build time, producing static HTML that can be served from a static server. Frameworks such as VuePress, VitePress, Gatsby and Docusaurus belong to this category.
Advantages: no server runtime, TTFB/FCP are pre‑computed.
Disadvantages: still needs a client bundle for hydration, and rebuilding is required when content changes.
ISG – Incremental Static Generation
ISG extends SSG by adding a server runtime that can re‑generate pages on demand using strategies like stale‑while‑revalidate , thus solving the rebuild‑pain of pure SSG.
Progressive Hydration
To reduce TTI, code‑splitting is used to split large components (e.g., Foo, Bar) into async chunks. The main bundle shrinks, allowing the page to become interactive earlier. React 18 introduces Selective Hydration to further improve this.
SSR with Streaming
Streaming SSR sends HTML to the browser as it is rendered (e.g., renderToNodeStream ), similar to ChatGPT’s streaming responses, improving perceived performance by reducing the time before the first bytes appear.
Selective Hydration
Selective Hydration builds on streaming SSR by skipping "slow components" (those that fetch data asynchronously, are large, or compute heavily) during the initial HTML output, then hydrating them later when ready.
function delay(time: number) {
return new Promise((resolve) => setTimeout(resolve, time))
}
/**
* Get crucial data
*/
function getCrucialData() {
return delay(1000).then(() => ({ data: Math.random() }))
}
function getData(time: number) {
return delay(time).then(() => ({ data: Math.random() }))
}
const Foo = async () => {
const data = await getData(1000)
return
foo: {data.data}
}
const Bar = async () => {
const data = await getData(2000)
return
bar: {data.data}
}
/**
* Page without selective hydration
*/
export default async function WithoutSelective() {
const crucialData = await getCrucialData()
return (
Without Selective
This page is rendered without Selective Hydration.
crucial data: {crucialData.data}
)
}Adding Suspense around slow components lets React skip them initially and stream their content later, improving TTFB while keeping total request time unchanged.
Islands Architecture
Islands Architecture (e.g., Astro) embraces a "no‑JavaScript" trend by rendering pages on the server and only loading JavaScript for interactive "islands". Each island hydrates independently, unlike progressive hydration which hydrates the whole tree later.
React Server Component (RSC)
RSC shares the goal of reducing client‑side JavaScript. Server Components run only on the server and do not require hydration, while Client Components run on both server and client and need hydration. A comparison table highlights differences in runtime, state, events, and async support.
Server Component
Client Component
Runtime
Server only
Server + client
JavaScript visibility
Invisible to client
Visible to client
Hydration
Not required
Required
Async support
Yes
No
State & context
No
Yes
Events / effects
No
Yes
Summary
The article maps the evolution of front‑end rendering techniques, showing how each approach addresses SEO, performance, and developer experience trade‑offs, and advises developers to understand the motivations behind each technology rather than chasing trends.
Further Reading
patterns.dev
Next.js documentation
Next.js Incremental Static Regeneration examples
reactwg/server-components
"Is 0kb of JavaScript in your Future?"
Islands Architecture
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.