Next.js 的 server 邊界:哪些留在框架,哪些丟出去

Next.js 把「server 能做的事」鋪得很滿,滿到很多人沒先想清楚就把東西全往裡塞。15 版(2024 年 10 月發布)之後 App Router、RSC 算是站穩了,工具夠成熟,反而更該回頭問一句:這四個縮寫,到底各自在解什麼問題,哪些東西適合留在框架的 server,哪些該丟出去。

先把四個縮寫分清楚

SSR 是每次請求都在 server 把頁面生出來,適合內容會隨人、隨時間變的頁面。SSG 是 build 的時候一次生好,之後就是靜態檔,適合那種「全世界看到的都一樣、改動不頻繁」的頁,行銷頁、文件站。ISR 卡在中間:先用快取的版本回,背景按需重生,讓你不必為了一點新鮮度就把整站打回 SSR,也不必每次內容微調就 rebuild 全站。這三個講的是同一件事的不同時間點,HTML 在「什麼時候、生幾次」。

RSC 是另一個維度。它重點在於「這段元件的 JS 要不要送到瀏覽器」。server component 在 server 跑完,把結果序列化送過去,那段邏輯與它拉進來的相依套件就不進 client bundle。這對 bundle size 是實打實的好處,資料抓取也可以更靠近 server。但它跟 SSR 不是同義詞,混在一起談就會開始講不清楚自己到底想要哪一段。

我看人踩坑,幾乎都是把「何時生 HTML」和「JS 送不送 client」這兩件事攪在一起。先在腦子裡把它們分成兩個獨立的軸,後面的決定才會清楚。

給瀏覽器的聚合,跟面向後端的風險邏輯

真正要劃的線不在這四個縮寫之間,在另一處:你寫在 server 上的這段碼,是「替瀏覽器把畫面要的資料聚合好」,還是「面向後端、跨服務、帶風險的邏輯」。

API routes、server actions、server components 都跑在 server,但責任不該混。前者是聚合:這個頁面要顯示的東西散在三五個下游,你在 Next 的 server 段把它們抓回來、拼成畫面需要的結構、順手裁掉用不到的欄位。這種「為這個畫面服務」的聚合,留在 Next server 很合理,它本來就最懂自己的頁面要什麼。

後者不一樣。跨多個服務的交易、寫入核心資料、帶著下游位址與內部認證的呼叫、第三方的 API key,這類東西我傾向丟出去,放獨立的 BFF 或後端服務,別塞進 framework server。理由跟我一貫的立場一致:邊界要靠結構扛住,不是靠自律。一段 server action 看起來人畜無害,但它能直接 import 到你的資料層、能讀到 env 裡的 key,你就是在賭哪段碼會不會不小心被牽進 client,賭 build 工具有沒有幫你切俐落。把帶風險的邏輯關在一個獨立、邊界清楚的服務裡,Next 這端連那些端點存在都不需要知道,這才是結構上的安全。

還有 lock-in。聚合邏輯綁在 Next 的 server runtime 上,問題不大,那本來就是展示層的一部分。但你把跨服務的核心邏輯、認證、對外整合全長在 server action 與 route handler 裡,哪天想換框架、想把這套搬到別的 runtime,會發現業務邏輯跟 Next 的執行模型纏死了。把這層抽到框架外,Next 對它來說只是其中一個 caller,換不換框架都不動它。

用之前,先承認它的成本

RSC 把該留在 server 的東西留在 server,方向沒有問題,代價則是多出一套邊界規則:"use client" 該畫在哪、哪些 props 能跨線序列化,都需要另外學。hydration 也有實際開銷,server 送來的標記要由 client 接手,在互動密集的頁面尤其明顯。

Next 生態確實有 lock-in。App Router 的 caching 行為與 RSC 邊界都屬於 framework 特定知識,學會的是「Next 怎麼想」,未必能轉用到其他 web stack;抽象一深,也容易失去對 HTTP 與瀏覽器行為的直覺。使用前先確認需要的是 SSG 的靜態速度、ISR 的按需更新,還是 RSC 的 bundle 瘦身,只開真正用得到的部分。能 build 仍不足以證明設計合理。

補充筆記

  • SSR / SSG / ISR 講的是 HTML 何時生、生幾次,RSC 講的是 JS 送不送 client,先當成兩條獨立的軸。
  • 給瀏覽器的畫面聚合留在 Next server 合理,它最懂自己頁面要什麼。
  • 跨服務、寫核心資料、帶下游認證與 key 的風險邏輯丟獨立 BFF,別塞進 framework server。
  • 安全靠結構不靠自律:把端點關在框架外,client 連它存在都不知道。
  • RSC 與 hydration 有真實成本與 lock-in,用之前先確定你要的是哪一段,別因為框架支援就全開。

觀點 Sheng,內文 Claude 協助 · 列入 20260613 blog 翻新計劃,新漆未乾。