部分预渲染 (Partial Prerendering)
到目前为止,您已经学习了静态渲染和动态渲染,以及如何流式传输依赖数据的动态内容。在本章中,我们将学习如何通过部分预渲染 (PPR) 在同一路由中结合静态渲染、动态渲染和流式传输。
部分预渲染是 Next.js 14 引入的实验性功能。随着该功能的稳定性进展,本页内容可能会更新。PPR 仅在 Next.js 的 canary 版本中可用(
next@canary
),稳定版 Next.js 中尚未提供。我们目前不建议在生产环境中使用部分预渲染。
要安装 Next.js 的 canary 版本,请运行:
静态路由与动态路由
对于当今构建的大多数 Web 应用,您需要为整个应用或特定路由选择静态渲染或动态渲染。在 Next.js 中,如果在路由中调用动态函数(如查询数据库),则_整个_路由将变为动态路由。
然而,大多数路由并非完全静态或动态。例如,考虑一个电商网站。您可能希望静态渲染产品信息页的大部分内容,但动态获取用户的购物车和推荐商品,从而向用户展示个性化内容。
回到您的仪表盘页面,您认为哪些组件是静态的,哪些是动态的?
准备好后,点击下方按钮查看我们如何拆分仪表盘路由:
什么是部分预渲染?
Next.js 14 引入了部分预渲染的实验版本——这是一种新的渲染模型,允许您在同一路由中结合静态渲染和动态渲染的优势。例如:

当用户访问路由时:
- 会提供包含导航栏和产品信息的静态路由外壳,确保快速初始加载。
- 外壳会留出动态内容(如购物车和推荐商品)的异步加载位置。
- 异步部分会并行流式传输,减少页面的整体加载时间。
部分预渲染如何工作?
部分预渲染使用 React 的 Suspense(您在前一章已学习过)来延迟渲染应用的某些部分,直到满足特定条件(如数据加载完成)。
Suspense 的 fallback 会嵌入初始 HTML 文件,与静态内容一起提供。在构建时(或重新验证期间),静态内容会被预渲染以创建静态外壳。动态内容的渲染会推迟到用户请求路由时。
用 Suspense 包裹组件不会使组件本身变为动态,而是将 Suspense 用作静态代码和动态代码之间的边界。
让我们看看如何在仪表盘路由中实现 PPR。
实现部分预渲染
通过在 next.config.ts
文件中添加 ppr
选项,为您的 Next.js 应用启用 PPR:
'incremental'
值允许您为特定路由采用 PPR。
接下来,在仪表盘布局中添加 experimental_ppr
段配置选项:
这样就完成了。在开发环境中,您可能不会注意到应用有何不同,但在生产环境中应该会看到性能提升。Next.js 会预渲染路由的静态部分,并将动态部分推迟到用户请求时再渲染。
部分预渲染的一大优势是您无需更改代码即可使用它。只要您使用 Suspense 包裹路由的动态部分,Next.js 就能识别路由的静态和动态部分。
我们相信 PPR 有潜力成为 Web 应用的默认渲染模型,结合静态站点和动态渲染的最佳特性。不过,它目前仍处于实验阶段。我们希望未来能使其稳定,并成为 Next.js 的默认构建方式。
您现在可以撤销这些更改,继续学习下一章。
总结
回顾一下,您已经为优化应用的数据获取做了以下几件事:
- 在与应用代码相同区域创建数据库,减少服务器与数据库之间的延迟。
- 使用 React 服务端组件在服务器上获取数据。这可以将昂贵的数据获取和逻辑保留在服务器端,减少客户端 JavaScript 包大小,并防止数据库密钥暴露给客户端。
- 使用 SQL 仅获取所需数据,减少每次请求传输的数据量以及内存中转换数据所需的 JavaScript 量。
- 在适当的情况下,使用 JavaScript 并行化数据获取。
- 实现流式传输,防止慢速数据请求阻塞整个页面,并允许用户在等待所有内容加载时就开始与 UI 交互。
- 将数据获取下移到需要它的组件,从而隔离路由中应该动态的部分。
在下一章中,我们将探讨数据获取时可能需要实现的两种常见模式:搜索和分页。