Next.js 部署與渲染模式
Next.js 的核心價值在於它是「混合式 (Hybrid)」框架。你不必被迫全站都用同一種渲染方式,而是可以針對每個頁面、甚至頁面中的每個區塊,選擇最適合的策略。
靜態生成 (Static Site Generation,SSG) - Default
在 App Router 中,如果一個頁面沒有使用動態函式(如 cookies(), headers())且沒有讀取 Search Params,它預設就是 靜態生成 (Static)。
動態路由的 SSG:generateStaticParams
如果你有動態路由 /posts/[id],但內容其實很少變動(如部落格),你可以在 Build Time 預先生成所有頁面。這取代了舊版的 getStaticPaths。
// app/posts/[id]/page.tsx
export async function generateStaticParams() {
const posts = await fetch('https://api.example.com/posts').then((res) => res.json());
return posts.map((post) => ({
id: String(post.id),
}));
}
export default function Page({ params }: { params: { id: string } }) {
// 這個頁面會在 build time 被生成靜態 HTML
return <Post id={params.id} />;
}
伺服器端渲染 (Server-Side Rendering, SSR) - Streaming
當頁面依賴即時數據(如使用者專屬內容)時,我們轉向 SSR。現代 Next.js 的 SSR 是 串流 (Streaming) 的。
Suspense 架構
我們可以將耗時的數據擷取包在 Server Component 中,並用 <Suspense> 包裹它。這樣瀏覽器可以先收到網頁外框 (Shell),等資料準備好後再嵌入內容。
import { Suspense } from 'react';
import { PostFeed } from './PostFeed';
import { Weather } from './Weather';
export default function Dashboard() {
return (
<section>
<h1>儀表板</h1>
{/* 天氣資訊可能很快 */}
<Suspense fallback={<p>載入天氣...</p>}>
<Weather />
</Suspense>
{/* 貼文列表可能很慢,不會阻塞天氣顯示 */}
<Suspense fallback={<p>載入貼文...</p>}>
<PostFeed />
</Suspense>
</section>
);
}
增量靜態再生 (Incremental Static Regeneration, ISR)
ISR 允許我們在應用程式運行時更新靜態頁面,無需重新 Build。
// 在 page.tsx 或 layout.tsx 設定
export const revalidate = 3600; // 每小時重新生成一次
局部預渲染 (Partial Prerendering, PPR)
這是 Next.js 14+ 引入的實驗性功能,旨在結合 SSG 的快速首屏與 SSR 的動態能力。
- 概念:頁面的外框 (Shell) 是靜態的(像 SSG),但其中的動態區塊(如購物車、使用者資訊)是動態載入的(像 SSR)。
- 優勢:瀏覽器可以在 TTFB (Time to First Byte) 極短的時間內收到靜態外框,無需等待後端資料庫查詢。
(需在 next.config.js 開啟 ppr: true 相關設定)
Runtime 選擇:Node.js vs Edge
Next.js 支援兩種執行環境:
| 特性 | Node.js Runtime (預設) | Edge Runtime |
|---|---|---|
| 適用場景 | 複雜邏輯、連接傳統資料庫 | Middleware, 電商個人化推薦 |
| 冷啟動 | 較慢 | 極快 (無 Serverless 冷啟動問題) |
| API 支援 | 完整 Node.js API | 僅 Web Standard API (fetch, Request) |
| 部署位置 | 單一區域 (Region) | 全球分發 (Global) |
欲切換至 Edge Runtime:
export const runtime = 'edge';
部署 (Deployment)
Vercel (官方推薦)
- 零設定:自動偵測 Next.js 設定。
- 全球 Edge Network:靜態資源自動 CDN 加速。
- ISR 支援:完美支援 On-demand Revalidation。
Docker (Self-hosted)
使用 Standalone 模式 可以大幅縮減 Docker Image 體積(通常從 >1GB 縮減至 ~100MB),因為它只會打包必要的 node_modules。
// next.config.mjs
export default {
output: 'standalone',
};
建置後,只需複製 .next/standalone 目錄即可運行。
小結
- 優先考慮 SSG (
generateStaticParams):效能最好,成本最低。 - 善用 Suspense 實現 Streaming SSR:讓使用者不需等待所有資料備齊就能看到畫面。
- PPR 是未來:持續關注 Partial Prerendering 的發展,它將模糊靜態與動態的邊界。