Next.js 15 完整升級指南:Turbopack 穩定版、React 19 支援、效能最佳化全攻略

深度解析 Next.js 15 所有新功能:Turbopack 正式穩定、快取機制重大變更、部分預渲染、Server Actions 增強,包含完整升級步驟與效能優化技巧

Next.js 15 完整升級指南
Next.js 15 完整升級指南

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 升級之旅吧!

作者:Drifter

·

更新:2025年8月8日 上午12:00

· 回報錯誤
下拉重新整理