如何使用部分預渲染 (Partial Prerendering)
部分預渲染 (Partial Prerendering, PPR) 是一種渲染策略,允許您在同一路由中結合靜態與動態內容。這能提升初始頁面效能,同時仍支援個人化的動態資料。

當使用者造訪路由時:
- 伺服器會傳送包含靜態內容的 外殼 (shell),確保快速的初始載入。
- 外殼會為動態內容預留 空洞 (holes),這些內容將非同步載入。
- 動態空洞會 並行串流 (streamed in parallel),減少頁面的整體載入時間。
🎥 觀看影片: 為什麼需要 PPR 及其運作原理 → YouTube (10 分鐘)。
部分預渲染如何運作?
要理解部分預渲染,需先熟悉 Next.js 提供的渲染策略。
靜態渲染 (Static Rendering)
靜態渲染會預先生成 HTML — 無論是在建置時或透過 重新驗證 (revalidation)。結果會被快取並在所有使用者和請求間共享。
在部分預渲染中,Next.js 會為路由預先渲染一個 靜態外殼 (static shell)。這可包含版面配置 (layout) 和任何不依賴請求時資料的元件。
動態渲染 (Dynamic Rendering)
動態渲染會在 請求時 (request time) 生成 HTML。這讓您能根據請求時資料提供個人化內容。
元件在以下情況會變為動態:
- 使用
cookies
- 使用
headers
- 使用
connection
- 使用
draftMode
- 使用
searchParams
屬性 - 使用
unstable_noStore
- 使用
fetch
並設定{ cache: 'no-store' }
在部分預渲染中,使用這些 API 會拋出特殊的 React 錯誤,告知 Next.js 該元件無法靜態渲染,導致建置錯誤。您可使用 Suspense 邊界包裝元件,延遲渲染至執行階段。
Suspense
React Suspense 用於延遲應用程式部分的渲染,直到滿足某些條件。
在部分預渲染中,Suspense 用於標記元件樹中的 動態邊界 (dynamic boundaries)。
在建置時,Next.js 會預先渲染靜態內容和 fallback
UI。動態內容會 延後 (postponed) 至使用者請求路由時才處理。
用 Suspense 包裝元件不會使元件本身變為動態(取決於您的 API 使用方式),而是將 Suspense 作為封裝動態內容的邊界,並啟用 串流 (streaming)。
串流 (Streaming)
串流將路由拆分為多個區塊 (chunks),並在準備完成時逐步串流至客戶端。這讓使用者能立即看到部分頁面內容,而無需等待整個內容完成渲染。

在部分預渲染中,以 Suspense 包裝的動態元件會從伺服器並行串流。

為減少網路開銷,完整回應 — 包含靜態 HTML 和串流的動態部分 — 會在 單一 HTTP 請求 中傳送。這避免了額外的往返,提升初始載入和整體效能。
啟用部分預渲染
您可透過在 next.config.ts
檔案中新增 ppr
選項來啟用 PPR:
'incremental'
值允許您為特定路由採用 PPR:
未設定 experimental_ppr
的路由預設為 false
,不會使用 PPR 進行預渲染。您需要為每個路由明確啟用 PPR。
須知事項:
experimental_ppr
會套用至路由區段的所有子項目,包含巢狀版面配置和頁面。您無需在每個檔案中新增,僅需在路由的頂層區段設定。- 若要為子區段停用 PPR,可在子區段中將
experimental_ppr
設為false
。
範例
動態 API
當使用需檢視傳入請求的動態 API 時,Next.js 會為路由啟用動態渲染。若要繼續使用 PPR,請以 Suspense 包裝元件。例如,<User />
元件因使用 cookies
API 而變為動態:
<User />
元件會以串流方式載入,而 <Page />
內的任何其他內容會被預先渲染並成為靜態外殼的一部分。
傳遞動態屬性 (props)
元件僅在存取值時才會啟用動態渲染。例如,若您從 <Page />
元件讀取 searchParams
,可將此值作為屬性傳遞至其他元件:
在表格元件內部,存取 searchParams
的值會使元件變為動態,而頁面其他部分會被預先渲染。