概览PPR 通过在 React Server Components 中使用 Suspense 包裹动态数据,使页面的静态部分可提前生成并缓存,动态部分在到达后以流式方式填充。该策略提升首屏与交互稳定性,适合列表壳体 + 动态详情等场景。页面结构与策略app/products/[id]/page.tsxexport const dynamic = 'force-static' import { Suspense } from 'react' export default async function ProductPage({ params }: { params: { id: string } }) { return ( <div> <Shell id={params.id} /> <Suspense fallback={<ReviewsSkeleton />}> {/* 动态插槽:在数据就绪时填充 */} {/* @ts-expect-error RSC */} <Reviews id={params.id} /> </Suspense> </div> ) } 动态组件(RSC)// app/products/[id]/Reviews.tsx export default async function Reviews({ id }: { id: string }) { const data = await fetch(`https://api.example.com/reviews/${id}`, { next: { revalidate: 300, tags: ['reviews'] }, }).then((r) => r.json()) return ( <ul> {data.items.map((it: any) => ( <li key={it.id}>{it.content}</li> ))} </ul> ) } Streaming 与缓存// app/products/[id]/Shell.tsx export default function Shell({ id }: { id: string }) { return ( <section> <h1>产品 {id}</h1> <p>静态外壳内容可被长时间缓存</p> </section> ) } // 骨架 export function ReviewsSkeleton() { return <p>评论加载中…</p> } 治理要点使用 `dynamic = 'force-static'` 将页面外壳静态化;对必须动态的 Route 使用 `dynamic = 'force-dynamic'`。将动态区块包裹在 Suspense,以流式填充减少首屏等待。结合缓存标签(`tags`)进行局部失效,避免全页重渲染。对错误场景提供 `error.tsx` 与边界,以避免流式失败影响整体体验。验证与指标浏览器:Chrome 120+、Safari 17+、Firefox 120+Next.js:15.0+;Node.js:20.x;RSC 与 Streaming:稳定首屏可感知时间显著降低;动态评论在 1–3s 内填充

发表评论 取消回复