Next.js 15 帶來了重大更新,包括 Turbopack 穩定版、React 19 支援、快取機制重新設計等關鍵功能。本指南將深入解析所有新功能,提供完整的升級步驟,並分享效能優化的最佳實踐。
🚀 Next.js 15 核心亮點一覽
Turbopack 正式穩定
經過長期開發,Turbopack 終於達到穩定狀態,成為 Next.js 15 的預設開發伺服器,取代了 Webpack。這意味著更快的開發體驗,不再需要 --turbo 標記。
React 19 前瞻支援
Next.js 15 提供 React 19 支援,同時保持與 React 18 的向後相容性,讓開發者可以提前準備應用程式的升級路徑。
快取機制重大變更
預設快取策略發生根本性變化,從「預設快取」轉為「預設不快取」,需要明確設定快取策略。
📋 升級前的準備工作
1. 檢查當前版本相容性
# 檢查當前 Next.js 版本
npm list next
# 檢查 React 版本
npm list react react-dom
2. 備份專案
# 建立備份分支
git checkout -b backup-before-nextjs15
git push origin backup-before-nextjs15
# 回到主要分支
git checkout main
3. 檢查依賴套件相容性
在升級前,檢查專案中使用的第三方套件是否支援 Next.js 15:
# 檢查套件更新
npm outdated
⬆️ 完整升級步驟
方法一:自動升級(推薦)
Next.js 15 提供自動升級 CLI 工具:
# 使用自動升級工具
npx @next/codemod@canary upgrade latest
這個工具會:
- 自動更新套件版本
- 執行必要的程式碼轉換
- 處理設定檔變更
- 提供升級報告
方法二:手動升級
如果需要更精細的控制,可以手動升級:
# 更新 Next.js 和 React
npm install next@latest react@latest react-dom@latest
# 或使用 yarn
yarn add next@latest react@latest react-dom@latest
# 或使用 pnpm
pnpm add next@latest react@latest react-dom@latest
3. 更新 TypeScript 設定(可選)
Next.js 15 支援 TypeScript 設定檔:
// next.config.ts
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
experimental: {
turbo: {
// Turbopack 設定
rules: {
'*.svg': {
loaders: ['@svgr/webpack'],
as: '*.js',
},
},
},
},
// 其他設定
}
export default nextConfig
🔄 重要的破壞性變更
1. 快取策略變更
影響範圍: GET Route Handlers 和 Client Router Cache
變更前 (Next.js 14):
// 預設會被快取
export async function GET() {
const data = await fetch('https://api.example.com/data')
return Response.json(data)
}
變更後 (Next.js 15):
// 需要明確設定快取
export async function GET() {
const data = await fetch('https://api.example.com/data', {
cache: 'force-cache' // 明確設定快取
})
return Response.json(data)
}
// 或使用 segment 設定
export const dynamic = 'force-static'
2. 客戶端路由快取
Next.js 15 將客戶端路由快取預設為不快取:
// app/layout.tsx
import { Suspense } from 'react'
export default function Layout({ children }) {
return (
<html>
<body>
{/* 使用 Suspense 優化載入體驗 */}
<Suspense fallback={<div>載入中...</div>}>
{children}
</Suspense>
</body>
</html>
)
}
⚡ Turbopack 穩定版功能詳解
自動啟用
Next.js 15 中 Turbopack 會自動啟用,無需額外設定:
# 以前需要
npm run dev -- --turbo
# 現在直接執行即可
npm run dev
效能提升數據
根據官方測試:
- 冷啟動速度: 提升 76.7%
- 檔案變更熱重載: 提升 96.3%
- 大型程式碼庫建置: 提升 87.2%
Turbopack 自定義設定
// next.config.ts
const nextConfig: NextConfig = {
experimental: {
turbo: {
rules: {
// SVG 處理
'*.svg': {
loaders: ['@svgr/webpack'],
as: '*.js',
},
// CSS 模組
'*.module.css': {
loaders: ['css-loader'],
as: '*.js',
},
},
resolveExtensions: [
'.mdx',
'.tsx',
'.ts',
'.jsx',
'.js',
'.mjs',
'.json',
],
},
},
}
🎯 新功能深度解析
1. 靜態路由指示器
開發模式下會顯示路由類型:
// app/page.tsx
export default function HomePage() {
return (
<div>
<h1>首頁</h1>
{/* 開發模式下會顯示 [Static] 指示器 */}
</div>
)
}
// app/user/[id]/page.tsx
export default function UserPage({ params }) {
return (
<div>
<h1>用戶: {params.id}</h1>
{/* 開發模式下會顯示 [Dynamic] 指示器 */}
</div>
)
}
2. 部分預渲染(實驗性功能)
啟用部分預渲染:
// next.config.ts
const nextConfig: NextConfig = {
experimental: {
ppr: 'incremental', // 或 true
},
}
實際應用範例:
// app/dashboard/page.tsx
import { Suspense } from 'react'
import StaticContent from './StaticContent'
import DynamicUserInfo from './DynamicUserInfo'
export default function Dashboard() {
return (
<div>
{/* 靜態部分會預渲染 */}
<StaticContent />
{/* 動態部分會延遲載入 */}
<Suspense fallback={<div>載入用戶資訊中...</div>}>
<DynamicUserInfo />
</Suspense>
</div>
)
}
3. Server Actions 增強
Server Actions 現在完全穩定:
// app/forms/contact/page.tsx
import { redirect } from 'next/navigation'
import { revalidatePath } from 'next/cache'
async function createContact(formData: FormData) {
'use server'
const name = formData.get('name') as string
const email = formData.get('email') as string
// 資料庫操作
await saveContact({ name, email })
// 重新驗證快取
revalidatePath('/contacts')
// 重新導向
redirect('/contacts/success')
}
export default function ContactForm() {
return (
<form action={createContact}>
<input name="name" placeholder="姓名" required />
<input name="email" type="email" placeholder="電子郵件" required />
<button type="submit">送出</button>
</form>
)
}
4. 增強表單 (next/form)
新的 next/form 組件提供客戶端導航:
import Form from 'next/form'
export default function SearchPage() {
return (
<Form action="/search">
<input name="query" placeholder="搜尋..." />
<button type="submit">搜尋</button>
</Form>
)
}
🔧 React 19 相容性指南
1. 啟用 React 19 支援
// package.json
{
"dependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0",
"next": "^15.0.0"
}
}
2. 新的 React 19 功能使用
// 使用 React 19 的 use() Hook
import { use, Suspense } from 'react'
function UserProfile({ userPromise }) {
const user = use(userPromise) // React 19 新功能
return (
<div>
<h2>{user.name}</h2>
<p>{user.email}</p>
</div>
)
}
export default function UserPage() {
const userPromise = fetch('/api/user').then(res => res.json())
return (
<Suspense fallback={<div>載入中...</div>}>
<UserProfile userPromise={userPromise} />
</Suspense>
)
}
🚀 效能優化最佳實踐
1. 快取策略優化
// app/api/data/route.ts
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const category = searchParams.get('category')
// 根據資料特性選擇快取策略
const data = await fetch(`https://api.example.com/data?category=${category}`, {
cache: category === 'static' ? 'force-cache' : 'no-store',
next: {
revalidate: category === 'dynamic' ? 60 : false
}
})
return Response.json(await data.json())
}
2. 映像最佳化
import Image from 'next/image'
export default function OptimizedGallery() {
return (
<div>
{/* 使用 Next.js 15 改進的 Image 組件 */}
<Image
src="/hero-image.jpg"
alt="主要圖片"
width={800}
height={600}
priority // 優先載入
placeholder="blur" // 模糊預留位置
blurDataURL="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ..." // 自定義模糊圖
/>
</div>
)
}
3. 程式碼分割優化
import dynamic from 'next/dynamic'
// 延遲載入重型組件
const HeavyChart = dynamic(() => import('./HeavyChart'), {
loading: () => <div>載入圖表中...</div>,
ssr: false // 僅在客戶端渲染
})
export default function Dashboard() {
return (
<div>
<h1>儀表板</h1>
<HeavyChart />
</div>
)
}
🛠️ 開發工具改進
1. TypeScript 支援增強
// next.config.ts - 現在支援 TypeScript 設定檔
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
// 完整的 TypeScript 支援
typescript: {
tsconfigPath: './tsconfig.build.json',
},
experimental: {
typedRoutes: true, // 型別安全的路由
},
}
export default nextConfig
2. ESLint 9 支援
// eslint.config.js - ESLint 9 設定
export default [
{
files: ['**/*.{js,jsx,ts,tsx}'],
languageOptions: {
ecmaVersion: 2024,
sourceType: 'module',
},
plugins: {
'@next/next': require('@next/eslint-plugin-next'),
},
rules: {
'@next/next/no-html-link-for-pages': 'error',
},
},
]
🔍 疑難排解指南
常見升級問題
問題 1: Turbopack 編譯錯誤
# 解決方案:清除快取
rm -rf .next
npm run dev
問題 2: 快取行為不如預期
// 檢查並明確設定快取策略
export const revalidate = 3600 // 1小時重新驗證
export const dynamic = 'force-static'
問題 3: TypeScript 類型錯誤
# 重新生成類型定義
npx next build
# 或
rm -rf .next/types && npm run dev
效能監控
// app/layout.tsx
export default function RootLayout({ children }) {
// 啟用效能監控
if (typeof window !== 'undefined' && 'performance' in window) {
window.addEventListener('load', () => {
console.log('FCP:', performance.getEntriesByName('first-contentful-paint')[0])
console.log('LCP:', performance.getEntriesByType('largest-contentful-paint')[0])
})
}
return (
<html>
<body>{children}</body>
</html>
)
}
🎯 升級後的驗證清單
功能測試
- 所有頁面正常渲染
- API 路由正常運作
- 表單提交功能正常
- 圖片最佳化正常
- 靜態資源載入正常
效能測試
- 建置時間改善
- 開發熱重載速度
- 首次內容繪製 (FCP)
- 最大內容繪製 (LCP)
- 互動時間 (TTI)
相容性測試
- 瀏覽器相容性
- 行動裝置測試
- SEO 功能正常
- 第三方整合正常
📈 Next.js 15 帶來的長期效益
開發體驗提升
- 更快的開發週期: Turbopack 大幅減少建置和熱重載時間
- 更好的除錯體驗: 改進的錯誤訊息和開發工具
- 型別安全: TypeScript 設定檔和型別路由
效能優化
- 更聰明的快取: 精確控制快取策略
- 更好的 SEO: 部分預渲染改善首次載入
- 更小的 Bundle: 改進的程式碼分割和樹搖優化
未來準備
- React 19 準備: 提前適應未來的 React 功能
- 現代化架構: 符合最新的網頁標準和最佳實踐
🎉 結語
Next.js 15 是一個重要的里程碑版本,帶來了顯著的效能改善和開發體驗提升。透過 Turbopack 的穩定化、快取機制的重新設計,以及 React 19 的前瞻支援,為現代網頁應用開發奠定了堅實的基礎。
建議開發者盡早升級以享受這些改進,同時注意處理破壞性變更,特別是快取策略的調整。透過本指南的詳細步驟和最佳實踐,你可以順利完成升級並充分發揮 Next.js 15 的潛力。
記住,升級不僅是版本號的改變,更是開發效率和應用效能的全面提升。現在就開始你的 Next.js 15 升級之旅吧!