伺服器元件 (Server Components)
React 伺服器元件 (Server Components) 讓您能撰寫可在伺服器端渲染並選擇性快取的 UI。在 Next.js 中,渲染工作會進一步按路由區段拆分,以實現串流 (Streaming) 和部分渲染,並提供三種不同的伺服器渲染策略:
本頁將介紹伺服器元件 (Server Components) 的運作原理、適用情境以及不同的伺服器渲染策略。
伺服器渲染的優勢
在伺服器端執行渲染工作有幾個優點:
- 資料獲取 (Data Fetching):伺服器元件 (Server Components) 讓您能將資料獲取移至伺服器端,更接近資料來源。這可以減少渲染所需資料的獲取時間,以及客戶端需要發送的請求數量,從而提升效能。
- 安全性 (Security):伺服器元件 (Server Components) 讓您能將敏感資料和邏輯(如令牌和 API 金鑰)保留在伺服器端,避免洩露給客戶端的風險。
- 快取 (Caching):透過伺服器端渲染,結果可以被快取並在後續請求和使用者之間重複使用。這能減少每次請求的渲染和資料獲取工作量,從而提升效能並降低成本。
- 效能 (Performance):伺服器元件 (Server Components) 提供了更多工具來優化基礎效能。例如,如果您的應用最初完全由客戶端元件 (Client Components) 組成,將非互動式的 UI 部分移至伺服器元件 (Server Components) 可以減少所需的客戶端 JavaScript 數量。這對於網路速度較慢或設備效能較低的用戶特別有益,因為瀏覽器需要下載、解析和執行的客戶端 JavaScript 更少。
- 初始頁面載入與 首次內容繪製 (FCP):在伺服器端,我們可以生成 HTML 讓使用者立即查看頁面,無需等待客戶端下載、解析和執行渲染頁面所需的 JavaScript。
- 搜尋引擎優化 (SEO) 與社交網路分享性:渲染後的 HTML 可供搜尋引擎機器人用來索引您的頁面,以及社交網路機器人用來生成頁面的社交卡片預覽。
- 串流 (Streaming):伺服器元件 (Server Components) 讓您能將渲染工作拆分為多個區塊,並在準備就緒時串流傳送至客戶端。這讓使用者能更早看到部分頁面內容,無需等待整個頁面在伺服器端完成渲染。
在 Next.js 中使用伺服器元件 (Server Components)
Next.js 預設使用伺服器元件 (Server Components)。這讓您無需額外配置即可自動實現伺服器端渲染,並可在需要時選擇使用客戶端元件 (Client Components),詳見客戶端元件 (Client Components)。
伺服器元件 (Server Components) 如何渲染?
在伺服器端,Next.js 使用 React 的 API 來協調渲染工作。渲染工作會按個別路由區段和 Suspense 邊界 (Suspense Boundaries) 拆分為多個區塊。
每個區塊的渲染分為兩個步驟:
- React 將伺服器元件 (Server Components) 渲染為一種特殊資料格式,稱為 React 伺服器元件負載 (RSC Payload)。
- Next.js 使用 RSC 負載和客戶端元件 (Client Components) 的 JavaScript 指令在伺服器端渲染 HTML。
接著,在客戶端:
- HTML 用於立即顯示路由的非互動式快速預覽(僅限初始頁面載入)。
- React 伺服器元件負載 (RSC Payload) 用於協調客戶端與伺服器元件樹,並更新 DOM。
- JavaScript 指令用於水合 (hydrate) 客戶端元件 (Client Components),讓應用程式變得可互動。
什麼是 React 伺服器元件負載 (RSC Payload)?
RSC 負載是渲染後的 React 伺服器元件樹的緊湊二進制表示。React 在客戶端使用它來更新瀏覽器的 DOM。RSC 負載包含:
- 伺服器元件 (Server Components) 的渲染結果
- 客戶端元件 (Client Components) 應渲染位置的佔位符及其 JavaScript 檔案的參考
- 從伺服器元件 (Server Components) 傳遞給客戶端元件 (Client Components) 的任何 props
伺服器渲染策略
伺服器渲染分為三種子類型:靜態 (Static)、動態 (Dynamic) 和串流 (Streaming)。
靜態渲染 (預設)
使用靜態渲染時,路由會在建置時或在資料重新驗證 (data revalidation) 後於背景渲染。結果會被快取並可推送至內容傳遞網路 (CDN)。這項優化讓您能在使用者和伺服器請求之間共享渲染工作的結果。
靜態渲染適用於路由包含非個人化且在建置時即可確定的資料,例如靜態部落格文章或產品頁面。
動態渲染
使用動態渲染時,路由會針對每個使用者在請求時進行渲染。
動態渲染適用於路由包含個人化資料或僅能在請求時確定的資訊,例如 cookies 或 URL 的搜尋參數 (search params)。
使用快取資料的動態路由
在大多數網站中,路由並非完全靜態或完全動態,而是一個連續光譜。例如,您可能有一個電子商務頁面,使用定期重新驗證的快取產品資料,同時也包含未快取的個人化客戶資料。
在 Next.js 中,您可以擁有同時包含快取和未快取資料的動態渲染路由。這是因為 RSC 負載和資料是分開快取的。這讓您能選擇動態渲染,而無需擔心在請求時獲取所有資料對效能的影響。
切換至動態渲染
在渲染過程中,如果發現動態函式 (dynamic functions) 或未快取的資料請求,Next.js 會切換為動態渲染整個路由。下表總結了動態函式和資料快取如何影響路由是靜態還是動態渲染:
動態函式 | 資料 | 路由 |
---|---|---|
否 | 已快取 | 靜態渲染 |
是 | 已快取 | 動態渲染 |
否 | 未快取 | 動態渲染 |
是 | 未快取 | 動態渲染 |
在上表中,要使路由完全靜態,所有資料必須已快取。然而,您可以擁有同時使用快取和未快取資料獲取的動態渲染路由。
作為開發者,您無需在靜態和動態渲染之間選擇,因為 Next.js 會根據使用的功能和 API 自動為每個路由選擇最佳渲染策略。相反,您選擇何時快取或重新驗證特定資料,並可選擇串流 (Streaming) 部分 UI。
動態函式
動態函式依賴僅能在請求時確定的資訊,例如使用者的 cookies、當前請求標頭或 URL 的搜尋參數 (search params)。在 Next.js 中,這些動態函式包括:
cookies()
和headers()
:在伺服器元件 (Server Components) 中使用這些函式會讓整個路由在請求時切換為動態渲染。searchParams
:在頁面 (Page) 上使用searchParams
prop 會讓該頁面在請求時切換為動態渲染。
使用任何這些函式都會讓整個路由在請求時切換為動態渲染。
串流 (Streaming)

串流讓您能逐步從伺服器渲染 UI。工作被拆分為區塊,並在準備就緒時串流傳送至客戶端。這讓使用者能在整個內容完成渲染前,立即看到部分頁面內容。

串流是 Next.js 應用路由器 (App Router) 的內建預設功能。這有助於提升初始頁面載入效能,以及依賴較慢資料獲取(會阻擋整個路由渲染)的 UI。例如,產品頁面上的評論。
您可以使用 loading.js
和 React Suspense 的 UI 元件來開始串流路由區段。詳見載入 UI 與串流 (Loading UI and Streaming) 章節以獲取更多資訊。