Skip to content

NextJs 渲染方式 ​

CSR(客户端渲染) ​

客户端渲染,在浏览器中下载 JS 后由 JS 渲染页面:

tsx
'use client'
import { useEffect, useState } from 'react'

export default function Home() {
  const [data, setData] = useState(null)

  useEffect(() => {
    setTimeout(() => setData({ id: 1 }), 5000)
  }, [])

  return <>{data ? <span>{data.id}</span> : 'Loading'}</>
}
'use client'
import { useEffect, useState } from 'react'

export default function Home() {
  const [data, setData] = useState(null)

  useEffect(() => {
    setTimeout(() => setData({ id: 1 }), 5000)
  }, [])

  return <>{data ? <span>{data.id}</span> : 'Loading'}</>
}

特点:

  • 初始 HTML 很小,TTFB(首字节时间)短
  • 网络差时 FCP(首屏渲染)长
  • SEO 不友好

SSR(服务端渲染) ​

服务端渲染,每次请求时在服务端生成 HTML:

tsx
// pages 目录下使用 getServerSideProps
export async function getServerSideProps() {
  const data = [{ id: 1, name: 'ljj' }]
  return { props: { data } }
}

export default function SSR({ data }) {
  return <span>{JSON.stringify(data)}</span>
}
// pages 目录下使用 getServerSideProps
export async function getServerSideProps() {
  const data = [{ id: 1, name: 'ljj' }]
  return { props: { data } }
}

export default function SSR({ data }) {
  return <span>{JSON.stringify(data)}</span>
}

特点:

  • 首屏加载快,FCP 短
  • TTFB 较长(需等待服务端请求完成)
  • SEO 友好
  • 每次请求都重新渲染

SSG(静态站点生成) ​

在构建时生成静态 HTML 文件:

无数据请求 ​

tsx
// 直接返回 JSX,构建时自动生成 HTML
export default function About() {
  return <>我是 About</>
}
// 直接返回 JSX,构建时自动生成 HTML
export default function About() {
  return <>我是 About</>
}

有数据请求 ​

tsx
export default function SSG({ data }) {
  return (
    <ul>{data.map(item => <li key={item.id}>{item.title}</li>)}</ul>
  )
}

export async function getStaticProps() {
  const res = await fetch('https://api.example.com/posts')
  const data = await res.json()
  return { props: { data } }
}
export default function SSG({ data }) {
  return (
    <ul>{data.map(item => <li key={item.id}>{item.title}</li>)}</ul>
  )
}

export async function getStaticProps() {
  const res = await fetch('https://api.example.com/posts')
  const data = await res.json()
  return { props: { data } }
}

动态路由 SSG ​

tsx
export default function Post({ post }) {
  return <><h1>{post.title}</h1><main>{post.body}</main></>
}

export async function getStaticPaths() {
  const res = await fetch('https://api.example.com/posts')
  const posts = await res.json()
  const paths = posts.map(post => ({ params: { id: String(post.id) } }))
  return { paths, fallback: false }
  // fallback: false  → 未匹配的路径返回 404
  // fallback: 'blocking' → 首次访问时 SSR 生成
}

export async function getStaticProps({ params }) {
  const res = await fetch(`https://api.example.com/posts/${params.id}`)
  const post = await res.json()
  return { props: { post } }
}
export default function Post({ post }) {
  return <><h1>{post.title}</h1><main>{post.body}</main></>
}

export async function getStaticPaths() {
  const res = await fetch('https://api.example.com/posts')
  const posts = await res.json()
  const paths = posts.map(post => ({ params: { id: String(post.id) } }))
  return { paths, fallback: false }
  // fallback: false  → 未匹配的路径返回 404
  // fallback: 'blocking' → 首次访问时 SSR 生成
}

export async function getStaticProps({ params }) {
  const res = await fetch(`https://api.example.com/posts/${params.id}`)
  const post = await res.json()
  return { props: { post } }
}

特点:

  • 构建时生成 HTML,访问速度最快
  • 适合内容不频繁变更的页面(博客、文档等)

ISR(增量静态再生) ​

在 SSG 基础上,按时间增量更新:

tsx
export async function getStaticProps({ params }) {
  const res = await fetch(`https://api.example.com/posts/${params.id}`)
  const post = await res.json()
  return {
    props: { post },
    revalidate: 3,  // 每 3 秒重新生成
  }
}
export async function getStaticProps({ params }) {
  const res = await fetch(`https://api.example.com/posts/${params.id}`)
  const post = await res.json()
  return {
    props: { post },
    revalidate: 3,  // 每 3 秒重新生成
  }
}

工作流程:

  1. 访问 SSG 页面 → 返回旧的 HTML
  2. Next.js 后台重新生成新 HTML
  3. 下次访问 → 返回新的 HTML

四种渲染方式对比 ​

CSRSSRSSGISR
渲染时机客户端每次请求构建时构建时 + 按需更新
数据新鲜度实时实时固定定时更新
FCP慢快最快快
TTFB短长短短
SEO差好好好
适用场景后台管理动态内容静态页面内容基本固定但需更新