Next.js 效能
規則
- 圖片:一律使用
next/image,並指定明確的 sizes;priority 僅用於 LCP 英雄區塊。字型:使用 next/font(不採用會阻塞渲染的 Google <link>)。
- 先測量再最佳化:使用
@next/bundle-analyzer、next build 輸出、Lighthouse。先修復最大的區塊。
- 對於重量級的客戶端專用小工具(圖表、編輯器),使用
dynamic(() => import(...), { ssr: false })。盡可能將初始 JS 保持在 200KB gz 以下。
- 積極快取:對於半動態頁面使用靜態 +
revalidate (ISR);使用 loading.tsx/Suspense 串流傳輸慢速部分,避免阻塞 TTFB。
- 避免瀑布效應:在 RSC 中平行處理,記憶化重複的
fetch(每個請求自動去重),對昂貴的計算使用 unstable_cache。
模式
import Image from 'next/image';
<Image src="/hero.jpg" alt="儀表板" width={1200} height={630} priority sizes="100vw" />
<Image src="/avatar.png" alt="使用者" width={64} height={64} sizes="64px" />
import { Inter } from 'next/font/google';
const inter = Inter({ subsets: ['latin'], display: 'swap' });
export default function RootLayout({ children }: { children: React.ReactNode }) {
return <html lang="en" className={inter.className}><body>{children}</body></html>;
}
import dynamic from 'next/dynamic';
const Chart = dynamic(() => import('@/components/chart'), { ssr: false, loading: () => <p>正在載入圖表…</p> });
export const revalidate = 60;
const withBundleAnalyzer = require('@next/bundle-analyzer')({ enabled: process.env.ANALYZE === 'true' });
module.exports = withBundleAnalyzer({});
檢查清單