Skip to content

Next.js 性能优化 ⚡

🎯 概述

性能优化是提升用户体验的关键。Next.js 提供了多种内置优化功能和最佳实践。

📦 图片优化

使用 Image 组件

tsx
import Image from 'next/image'

export default function Page() {
  return (
    <Image
      src="/hero.jpg"
      alt="Hero"
      width={1200}
      height={600}
      priority // 优先加载
      placeholder="blur" // 模糊占位符
    />
  )
}

响应式图片

tsx
<Image
  src="/hero.jpg"
  alt="Hero"
  fill
  sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
  style={{ objectFit: 'cover' }}
/>

🚀 代码分割

动态导入

tsx
import dynamic from 'next/dynamic'

const DynamicComponent = dynamic(() => import('@/components/Heavy'), {
  loading: () => <p>加载中...</p>,
  ssr: false // 禁用 SSR
})

export default function Page() {
  return <DynamicComponent />
}

条件加载

tsx
'use client'

import { useState } from 'react'
import dynamic from 'next/dynamic'

const Chart = dynamic(() => import('@/components/Chart'), {
  ssr: false
})

export default function Dashboard() {
  const [showChart, setShowChart] = useState(false)
  
  return (
    <div>
      <button onClick={() => setShowChart(true)}>显示图表</button>
      {showChart && <Chart />}
    </div>
  )
}

📝 字体优化

tsx
import { Inter } from 'next/font/google'

const inter = Inter({
  subsets: ['latin'],
  display: 'swap',
  preload: true
})

export default function RootLayout({ children }) {
  return (
    <html className={inter.className}>
      <body>{children}</body>
    </html>
  )
}

🎨 缓存策略

数据缓存

tsx
// 静态数据 - 长时间缓存
const data = await fetch('url', {
  next: { revalidate: 3600 }
})

// 动态数据 - 不缓存
const data = await fetch('url', {
  cache: 'no-store'
})

路由缓存

tsx
// app/page.tsx
export const revalidate = 3600 // 1小时

export default async function Page() {
  const data = await getData()
  return <div>{data.title}</div>
}

📊 性能监控

Web Vitals

tsx
// app/layout.tsx
import { Analytics } from '@vercel/analytics/react'

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Analytics />
      </body>
    </html>
  )
}

自定义监控

tsx
// app/web-vitals.tsx
'use client'

import { useReportWebVitals } from 'next/web-vitals'

export function WebVitals() {
  useReportWebVitals((metric) => {
    console.log(metric)
    // 发送到分析服务
  })
}

📚 最佳实践

1. 使用 Suspense 和 Streaming

tsx
import { Suspense } from 'react'

export default function Page() {
  return (
    <div>
      <h1>快速内容</h1>
      <Suspense fallback={<Loading />}>
        <SlowComponent />
      </Suspense>
    </div>
  )
}

2. 优化第三方脚本

tsx
import Script from 'next/script'

export default function Page() {
  return (
    <>
      <Script
        src="https://example.com/script.js"
        strategy="lazyOnload" // 延迟加载
      />
    </>
  )
}

3. 减少 JavaScript 包大小

tsx
// 使用 tree-shaking
import { specific } from 'library'

// 避免导入整个库
// import * as library from 'library'

4. 预加载关键资源

tsx
import Link from 'next/link'

<Link href="/dashboard" prefetch={true}>
  仪表板
</Link>

🔗 相关资源


下一步:学习 Next.js SEO 优化