Partial Prerendering(PPR)是 Next.js 的一个实验性特性, 它允许在同一个页面中混合静态渲染和动态渲染。
核心概念:
Suspense 边界定义 HolesPPR 是实验性特性,需要在 next.config.ts 中启用:
// next.config.ts
const nextConfig = {
experimental: {
ppr: true,
},
};
export default nextConfig;⚠️ 警告:PPR 仍在实验阶段,API 可能会变化,不建议在生产环境使用。
这部分内容在构建时生成,所有用户看到相同的内容。
构建时间:2025-12-17T09:54:12.774Z
✅ 多次刷新页面,这个时间保持不变
这部分在请求时渲染,每次访问都会更新
渲染时间:2025-12-17T09:54:12.775Z
✅ 每次刷新都会变化
这部分在请求时渲染,每次访问都会更新
渲染时间:2025-12-17T09:54:12.775Z
✅ 每次刷新都会变化
1️⃣ 构建时
2️⃣ 请求时
3️⃣ 用户体验
在 next.config.ts 中添加 experimental.ppr: true
pnpm build构建日志中会显示使用 PPR 的页面
- 静态 Shell 的构建时间不变
- 动态 Holes 的渲染时间每次都变化
页面首先返回 Shell HTML,然后通过 Streaming 更新 Holes
// app/product/[id]/page.tsx
import { Suspense } from 'react';
// 动态组件 - Hole
async function DynamicStock({ productId }) {
const stock = await fetchStock(productId); // 实时库存
return <div>库存:{stock}</div>;
}
export default async function ProductPage({ params }) {
// 静态内容 - Shell
const product = await fetchProduct(params.id);
return (
<div>
{/* Shell:静态部分 */}
<h1>{product.name}</h1>
<p>{product.description}</p>
<img src={product.image} alt={product.name} />
{/* Hole:动态部分 */}
<Suspense fallback={<div>Loading stock...</div>}>
<DynamicStock productId={params.id} />
</Suspense>
</div>
);
}