首页 / Next.js 16 入门教程 / 渲染哲学

Next.js 16 入门教程

渲染哲学

本教程共 42 篇 · 第 38 篇 · 更新于 2026-07-30 · 约 7 分钟阅读

Next.jsNext.js 16 入门教程渲染SSRSSGISR流式渲染PPR

38. 渲染哲学

本节目标:理解 Next.js 独特的组件级渲染模型,掌握不同渲染方式的权衡,学会为场景选择最合适的渲染策略。

静态与动态是光谱

大多数框架在路由层面做静态/动态的二选一:一个页面要么构建时生成,要么每次请求时渲染。

Next.js 不一样。静态和动态的边界在组件级别,不在路由级别。 同一个页面可以同时包含:

  • 立即渲染的静态外壳
  • 独立缓存的函数
  • 流式传输的动态内容

这让开发者可以精细控制每个部分的渲染行为,而不是被迫做非此即彼的选择。

渲染方式对比

SSG(Static Site Generation)

构建时生成 HTML,每次请求直接返回同一个文件。

优点:加载最快、CDN 友好、托管成本低 缺点:内容更新需要重新构建

适合:营销页面、文档、博客文章

SSR(Server-Side Rendering)

每次请求时在服务端生成 HTML。

优点:内容总是最新的、可以访问请求信息 缺点:服务器压力大、响应速度依赖服务端性能

适合:个性化页面、实时数据、依赖 cookies/headers 的页面

ISR(Incremental Static Regeneration)

构建时生成静态页面,但可以在运行时按需更新。

优点:兼顾静态页面的速度和动态内容的灵活性 缺点:首次访问可能拿到过期数据

适合:电商产品列表、新闻网站、大型内容站点

CSR(Client-Side Rendering)

服务端返回空 HTML,由 JavaScript 在浏览器中渲染。

优点:服务器压力最小、交互体验流畅 缺点:首屏加载慢、SEO 不友好

适合:后台管理系统、高度交互的应用

ISR 实战

基于时间的重新验证

// app/blog/[id]/page.tsx
import { cacheLife } from 'next/cache'

export default async function Page({ params }) {
  const { id } = await params
  const post = await getPost(id)
  return <article>{post.content}</article>
}

async function getPost(id: string) {
  'use cache'
  cacheLife('minutes') // 1 分钟后标记为过期
  return fetch(`https://api.example.com/posts/${id}`).then(r => r.json())
}
Note

Next.js 16 启用 Cache Components 后,export const revalidate = 60 等路由段配置已被移除。请使用 cacheLife 配合 "use cache" 指令实现基于时间的重新验证。

工作流程:

  1. 构建时生成所有已知页面的静态版本
  2. 请求到来时直接返回缓存(瞬间响应)
  3. 60 秒后,下一个请求仍返回过期缓存
  4. 后台开始重新生成新版本
  5. 生成完成后替换缓存

按需重新验证

revalidatePathrevalidateTag 主动触发更新:

// app/actions.ts
'use server'

import { revalidatePath } from 'next/cache'

export async function publishPost(id: string) {
  await db.posts.update(id, { published: true })
  revalidatePath(`/posts/${id}`) // 立即重新验证
}
// 给 fetch 打标签
const data = await fetch('https://api.example.com/posts', {
  next: { tags: ['posts'] },
})
// 按标签重新验证
revalidateTag('posts', 'max')

组件级渲染模型

三种渲染模型的对比

模型静态/动态边界灵活性基础设施复杂度
构建时预渲染页面
路由级边界路由
组件级边界组件

Next.js 选择了组件级边界,这意味着:

  1. 流式传输:静态和动态内容在同一个响应中发送
  2. 缓存协调:多个实例之间需要同步缓存失效
  3. 缓存一致性:HTML 和 RSC Payload 必须保持同步

基础设施要求

组件级渲染模型对托管平台有要求:

  • 流式传输:服务器必须支持分块发送响应
  • 缓存协调:多实例部署时需要共享缓存失效信息
  • CDN 集成:PPR 的静态外壳需要 CDN 能存储并恢复动态渲染

流式渲染

Next.js 用流式 SSR 来优化用户体验。服务器先发送页面的静态部分,动态内容准备好后再流式传输。

import { Suspense } from 'react'

export default function Page() {
  return (
    <div>
      <header>立即渲染的头部</header>
      <Suspense fallback={<div>加载中...</div>}>
        <DynamicContent /> {/* 流式传输 */}
      </Suspense>
    </div>
  )
}

用户不用等所有内容都准备好,先看到页面框架,再逐步填充数据。

Partial Prerendering (PPR)

PPR 是 Next.js 16 的新模式,把页面分成静态外壳和动态部分:

// next.config.ts
import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  cacheComponents: true,
}

export default nextConfig
  • 静态外壳:包含导航、布局等,可以预渲染和缓存
  • 动态部分:包含个性化数据,流式传输

PPR 在 Next.js 16 中的工作方式与 15 的 canary 版本不同。如果你在用 15 的 PPR,建议先停留在当前版本。

选择渲染策略

决策树

需要用户特定数据?
├── 是 -> SSR 或流式渲染
└── 否 -> 数据多久更新一次?
    ├── 实时 -> SSR
    ├── 定期 -> ISR
    └── 几乎不变 -> SSG

实用建议

  1. 默认用静态:除非有理由,否则尽量静态渲染
  2. 按需加动态:只在需要的地方用 dynamic 或流式
  3. ISR 是折中方案:内容多但更新不频繁的场景
  4. CSR 留给后台:不需要 SEO 的管理界面

平台兼容性

不是所有部署平台都支持 Next.js 的全部特性:

部署方式流式ISRPPR
Vercel
Node.js 服务器
Docker
静态导出

自托管时,ISR 需要额外配置共享缓存才能在多实例间同步。

渲染策略没有银弹。搞清楚每种方式的取舍,按实际场景选就行。