2026/08/26

本文內容以以下版本為基準:
{
"next": "16.3.3",
"react": "19.2.8",
"@tanstack/react-query": "5.102.3"
}本文主要以 Next.js App Router 為例,整理 CSR、SSR、SSG、ISR、PPR、RSC 與 Client Component 之間的差異。
Next.js 的 Rendering 與 Cache 機制仍持續演進,不同版本的實際行為請以對應版本官方文件為準。
在學 Next.js 時,很容易同時看到:
每個縮寫都長得像考試範圍,但其實它們不是全部都在講同一件事。
最重要的是先分清楚:
有些是在講「什麼時候 Render」,有些是在講「React Component 在哪裡執行」。
| 模式 | 全名 | 主要在哪裡 Render | 特性 |
|---|---|---|---|
| CSR | Client-Side Rendering | Browser | JS 載入後才產生 UI |
| SSR | Server-Side Rendering | Server,每次 Request | 每次請求即時產生 |
| SSG | Static Site Generation | Build time | Build 時預先產生 |
| ISR | Incremental Static Regeneration | Build + 後續更新 | 靜態內容可以重新產生 |
| PPR | Partial Prerendering | Static + Request-time | 同頁混合靜態與動態內容 |
典型 React SPA 通常就是 CSR。
Browser ↓載入 HTML + JS ↓React 執行 ↓取得 API ↓Render UI例如:
ViteReactReact RouterTanStack Query通常就是這種模式。
CSR 的優點是前端互動彈性很高,但初始畫面通常需要等待 JavaScript 執行與資料取得。
SPA 全名是:
Single Page Application
但 SPA 其實比較偏向「應用程式架構」,不是單純的 Rendering Strategy。
例如:
/products ↓/products/123 ↓/cart切換頁面時不會重新載入整份 HTML,而是由 JavaScript 處理 routing。
所以常見情況是:
SPA 通常搭配 CSR。
但兩個不能完全畫上等號。
Next.js 也可以做到 client-side navigation,但不代表整個網站就是傳統 CSR SPA。
SSR 的概念很簡單:
User Request ↓Server ↓Render HTML / RSC ↓Response例如使用者資料:
import { cookies } from 'next/headers'
export default async function Page() {
const cookieStore = await cookies()
const user = await getUser(cookieStore)
return <Dashboard user={user} />
}因為 Cookie、Session 只有 Request 進來時才知道,所以這類內容適合 Request-time Rendering。
常見用途:
SSG 是:
在 Build 階段先把內容產生好。
例如:
export default function AboutPage() {
return <h1>About</h1>
}Build:
next build ↓產生內容 ↓之後使用者直接拿現成結果適合:
優點通常是速度快,而且不需要每次 Request 都重新運算。
ISR 可以理解成:
SSG + Revalidation
內容一開始先產生,但之後可以重新生成新版。
例如 Next.js 16:
import { cacheLife } from 'next/cache'
async function getPosts() {
'use cache'
cacheLife('hours')
return db.post.findMany()
}概念:
Build ↓Version A ↓使用者取得 A ↓一段時間後重新產生 ↓Version B所以很適合:
這些資料不是每秒更新,但也不能永遠不變。
PPR 全名:
Partial Prerendering
這是現在 Next.js 很重要的概念。
以前比較容易把頁面想成:
StaticvsDynamic但實際網站通常不是這麼單純。
例如商品頁:
<ProductPage>
<Header />
<ProductInfo />
<Suspense fallback={<Skeleton />}>
<UserCart />
</Suspense>
</ProductPage>其中:
ProductPage├─ Header│ └─ 可以預先 Render│├─ ProductInfo│ └─ Cached│└─ UserCart └─ Request-timePPR 可以讓:
Header + ProductInfo先送給使用者。
然後:
UserCart再透過 Suspense stream 回來。
所以不用因為頁面裡有一小塊 Dynamic Content,就整頁全部等待 SSR。
RSC 是:
React Server Components
這跟 SSR、SSG、ISR 不是完全同一層概念。
RSC 描述的是:
React Component 在 Server 還是 Client 執行。
例如:
export default async function Page() {
const posts = await db.post.findMany()
return <PostList posts={posts} />
}這是一個 Server Component。
但這個 Component 最後可能:
所以:
RSC ≠ SSRServer Component 不代表一定每次 Request 都重新 Render。
例如:
'use client'
export function Counter() {
// interactive UI
}這是 Client Component。
但整個 Page 仍然可能是 Server Render 出來的。
所以:
Client Component≠整頁 CSRClient Component 比較代表:
這段 React 需要在 Browser 執行與 Hydrate。
例如:
不要把全部名詞混在同一張表。
CSRSSRSSGISRPPR回答的是:
這份內容什麼時候被產生?
Server ComponentClient Component回答的是:
這個 React Component 在哪裡執行?
這樣就比較不容易混亂。
例如:
Product Page│├─ Header│ └─ SSG / Cached Server Component│├─ Product Info│ └─ ISR / Cached Server Component│├─ User Profile│ └─ SSR / Request-time Server Component│└─ Add To Cart Button └─ Client Component再透過 PPR:
先送:Header + Product Info 再 Stream:User Profile Browser:Client Component 接手互動所以現在問:
Next.js 是 SSR 還是 SPA?
其實已經不太精確。
更好的問題是:
這個頁面的哪些內容是預先產生、哪些需要 Request-time、哪些需要在 Client 執行?
| 名詞 | 最簡單的理解 |
|---|---|
| CSR | Browser Render |
| SPA | 不重新載入整頁的應用架構 |
| SSR | 每次 Request 由 Server Render |
| SSG | Build 時預先 Render |
| ISR | Static Content 可以重新產生 |
| PPR | 同頁混合 Static 與 Dynamic |
| RSC | React Component 在 Server 執行 |
| Client Component | React Component 在 Browser 執行 |
最重要的觀念是:
現代 Next.js 不需要整個網站只選 SSR、SSG 或 CSR 其中一種。
同一個頁面可以混合 Static、Cached、Request-time 與 Client-side Interactive Content。
也因此,比起問「這個網站是哪一種模式」,現在更值得問的是:
每一塊內容究竟需要在哪裡、什麼時候 Render?
當這個問題想清楚,SSR、SSG、ISR、PPR 這些縮寫就不會再像一群專門來佔記憶體的英文字母。