伺服器元件 (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) 拆分為多個區塊。

每個區塊的渲染分為兩個步驟:

  1. React 將伺服器元件 (Server Components) 渲染為一種特殊資料格式,稱為 React 伺服器元件負載 (RSC Payload)
  2. Next.js 使用 RSC 負載和客戶端元件 (Client Components) 的 JavaScript 指令在伺服器端渲染 HTML

接著,在客戶端:

  1. HTML 用於立即顯示路由的非互動式快速預覽(僅限初始頁面載入)。
  2. React 伺服器元件負載 (RSC Payload) 用於協調客戶端與伺服器元件樹,並更新 DOM。
  3. 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 負載和資料是分開快取的。這讓您能選擇動態渲染,而無需擔心在請求時獲取所有資料對效能的影響。

了解更多關於全路由快取 (full-route cache)資料快取 (Data Cache)

切換至動態渲染

在渲染過程中,如果發現動態函式 (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。工作被拆分為區塊,並在準備就緒時串流傳送至客戶端。這讓使用者能在整個內容完成渲染前,立即看到部分頁面內容。

客戶端部分渲染頁面圖表,顯示正在串流的區塊載入 UI。

串流是 Next.js 應用路由器 (App Router) 的內建預設功能。這有助於提升初始頁面載入效能,以及依賴較慢資料獲取(會阻擋整個路由渲染)的 UI。例如,產品頁面上的評論。

您可以使用 loading.jsReact Suspense 的 UI 元件來開始串流路由區段。詳見載入 UI 與串流 (Loading UI and Streaming) 章節以獲取更多資訊。

On this page