如何使用部分预渲染 (Partial Prerendering)
部分预渲染 (PPR) 是一种渲染策略,允许您在同一路由中结合静态与动态内容。这既能提升初始页面性能,又能支持个性化动态数据。

当用户访问路由时:
- 服务器发送包含静态内容的 外壳 (shell),确保快速初始加载。
- 外壳为动态内容预留 空洞 (holes),这些内容将异步加载。
- 动态空洞会 并行流式传输,减少页面整体加载时间。
🎥 观看视频: PPR 原理及工作方式 → YouTube (10分钟)。
部分预渲染如何工作?
理解部分预渲染前,需熟悉 Next.js 提供的渲染策略。
静态渲染
静态渲染会提前生成 HTML——在构建时或通过 重新验证 完成。结果会被缓存并在用户和请求间共享。
在部分预渲染中,Next.js 会为路由预渲染 静态外壳,可包含布局及不依赖请求时数据的组件。
动态渲染
动态渲染在 请求时 生成 HTML,允许基于请求时数据提供个性化内容。
组件在以下情况下会变为动态:
- 使用
cookies
- 使用
headers
- 使用
connection
- 使用
draftMode
- 使用
searchParams
属性 - 使用
unstable_noStore
- 使用
{ cache: 'no-store' }
选项的fetch
在部分预渲染中,使用这些 API 会触发特殊的 React 错误,提示 Next.js 该组件无法静态渲染,导致构建错误。您可以用 Suspense 边界包裹组件以延迟渲染至运行时。
Suspense
React 的 Suspense 用于延迟渲染部分应用直至条件满足。
在部分预渲染中,Suspense 用于标记组件树中的 动态边界。
构建时,Next.js 会预渲染静态内容和 fallback
UI。动态内容会 延迟 至用户请求路由时加载。
用 Suspense 包裹组件不会使组件本身变为动态(API 使用决定动态性),而是作为封装动态内容并启用 流式传输 的边界。
流式传输
流式传输将路由拆分为多个块,并在准备就绪时逐步流式传输至客户端。这让用户能在全部内容渲染完成前立即看到部分页面。

在部分预渲染中,包裹在 Suspense 中的动态组件会从服务器并行流式传输。

为减少网络开销,完整响应(包括静态 HTML 和流式动态部分)通过 单次 HTTP 请求 发送。这避免了额外往返,提升了初始加载和整体性能。
启用部分预渲染
通过将 ppr
选项加入 next.config.ts
文件启用 PPR:
'incremental'
值允许您为特定路由启用 PPR:
未设置 experimental_ppr
的路由默认为 false
,不会使用 PPR 预渲染。您需要为每个路由显式启用 PPR。
须知:
experimental_ppr
会应用于路由段的所有子级,包括嵌套布局和页面。无需在每个文件中添加,只需在路由的顶层段设置。- 要为子段禁用 PPR,可在子段中将
experimental_ppr
设为false
。
示例
动态 API
使用需要查看传入请求的动态 API 时,Next.js 会为该路由启用动态渲染。要继续使用 PPR,需用 Suspense 包裹组件。例如,<User />
组件因使用 cookies
API 而变为动态:
<User />
组件将被流式传输,而 <Page />
内的其他内容会被预渲染并成为静态外壳的一部分。
传递动态属性
仅当访问值时组件才会启用动态渲染。例如,若从 <Page />
组件读取 searchParams
,可将其作为属性传递给其他组件:
在表格组件内部,访问 searchParams
的值会使该组件变为动态,而页面其余部分会被预渲染。