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 秒重新生成
}
}工作流程:
- 访问 SSG 页面 → 返回旧的 HTML
- Next.js 后台重新生成新 HTML
- 下次访问 → 返回新的 HTML
四种渲染方式对比
| CSR | SSR | SSG | ISR | |
|---|---|---|---|---|
| 渲染时机 | 客户端 | 每次请求 | 构建时 | 构建时 + 按需更新 |
| 数据新鲜度 | 实时 | 实时 | 固定 | 定时更新 |
| FCP | 慢 | 快 | 最快 | 快 |
| TTFB | 短 | 长 | 短 | 短 |
| SEO | 差 | 好 | 好 | 好 |
| 适用场景 | 后台管理 | 动态内容 | 静态页面 | 内容基本固定但需更新 |
Cao Note