关于 nextjs-ppr-patterns
面向 Next.js 16 App Router 与 Cache Components 的 Partial Prerendering 编写和审查参考技能。21 条规则涵盖静态与动态边界、缓存、运行时数据、页面组合、表单和变更操作。
主要功能
- 01分为 6 类的 21 条规则
- 02使用 Cache Components 启用 PPR
- 03为动态内容设置 Suspense 边界
- 04配置缓存与失效
- 05组合流式页面和仪表板
- 06处理表单、变更操作与向导
适用场景
- 01构建包含静态与个性化内容的页面
- 02从已移除的实验性 PPR 标志迁移
- 03排查未缓存数据的边界错误
- 04组合流式仪表板或多步骤表单
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ pproenca/ dot-skills --skill nextjs-ppr-patterns安装后在 Claude Code 中输入/nextjs-ppr-patterns确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
AGENTS.mdmetadata.jsonassets/templates/_template.mdreferences/_debug-boundaries.md_sections.mdcache-in-memory-not-durable-serverless.mdcache-keys-are-automatic.mdcache-pass-runtime-values-as-props.mdcache-pass-through-children-and-actions.mdcache-set-lifetime-and-tags.mdcache-use-cache-directive.mdcompose-do-not-opt-out-the-shell.mdcompose-parallel-holes.mdcompose-single-dynamic-hole.mdcompose-stream-to-client-with-use.mdmutate-updatetag-vs-revalidatetag.mdmutate-wizard-url-driven-steps.mdruntime-gate-nondeterminism-with-connection.mdruntime-keep-param-routes-static.mdruntime-request-apis-force-a-boundary.mdsetup-dynamic-by-default.mdsetup-enable-cache-components.mdshell-place-boundaries-low.mdshell-suspense-does-not-force-dynamic.mdshell-suspense-is-the-boundary.mdshell-wrap-uncached-data.md详细介绍
Next.js 16 部分预渲染模式
适用于 Next.js 16 App Router、采用 Cache Components 模型的部分预渲染(PPR)——PPR 会带来哪些决策,以及如何做出选择。本文旨在让 Agent 在编写或审查代码时应用这些规则。共包含 6 个类别中的 21 条规则,从简单到复杂依次排列:启用 PPR → 理解静态/动态边界 → 缓存 → 处理运行时数据 → 组合完整页面 → 构建表单和向导。每条规则都针对模型默认沿用 Next.js 14/15 时会出现的特定错误默认做法;对于模型本来就能正确处理的内容,不设规则。
版本特定。 本技能面向 Next.js 16(通过
cacheComponents使用 PPR,React 19.2)。Next.js 14/15 的experimental.ppr标志和export const experimental_ppr路由导出已被移除——请参阅setup-enable-cache-components。迁移现有应用请参阅迁移指南。
先编写,再验证。 这些规则用于编写 PPR,无法告诉你实际渲染了什么。若要通过实证拆解边界——对比静态外壳与水合后的 DOM,找出动态空缺、定位
'use client'岛、测量加载情况,并解释路由为何是动态的——请根据 _debug-boundaries.md 运行next build并使用真实浏览器。
适用场景
- 构建或审查混合静态界面元素与个性化、实时或按请求变化内容的 Next.js 16 页面
- 启用或迁移 PPR(
cacheComponents),或发现无效的experimental.ppr/experimental_ppr代码 - 决定
<Suspense>边界的位置,或排查Uncached data was accessed outside of <Suspense>构建错误 - 添加
'use cache'、cacheLife、cacheTag,或在变更后选择使用updateTag/revalidateTag/refresh - 组合表单、多步骤向导、仪表板,或将流式服务器数据传入交互式客户端组件
- 通过实证验证或排查实际渲染结果——哪些部分属于静态外壳、哪些部分以流式方式传输、CSR/SSR 边界在哪里,以及路由为何变成动态
规则类别
| # | 类别 | 前缀 | 涵盖内容 |
|---|---|---|---|
| 1 | 设置与心智模型 | setup- | 通过 cacheComponents 启用 PPR;已移除的实验性标志;默认动态 / 可选择启用缓存的反转 |
| 2 | Suspense 边界 | shell- | <Suspense> 作为静态/动态分界;构建错误;边界粒度;Suspense 不会 做什么 |
| 3 | 使用 'use cache' 进行缓存 | cache- | 指令级别;自动生成的键;将运行时值作为属性传入;透传;cacheLife/cacheTag;无服务器环境中的持久性 |
| 4 | 运行时 API 与非确定性 | runtime- | 异步请求 API 会强制要求边界;generateStaticParams;使用 connection() 获取随机值/时间 |
| 5 | 页面组合方案 | compose- | 单个空缺 → 并行仪表板 → Promise + use() 流式传输 → 避免让整个应用退出静态外壳 |
| 6 | 表单、变更与向导 | mutate- | updateTag 与 revalidateTag、refresh 的区别;由 URL 驱动的向导步骤;<Activity> 保留字段内容 |
快速参考
1. 设置与心智模型
setup-enable-cache-components— 通过cacheComponents: true启用 PPR;experimental.ppr/experimental_ppr标志已移除setup-dynamic-by-default— 所有内容都在请求时渲染;通过'use cache'可选择启用缓存(且fetch不再默认缓存)
2. Suspense 边界
shell-suspense-is-the-boundary—<Suspense>是静态外壳与动态流之间的分界线,而不是加载指示器shell-wrap-uncached-data— 未缓存/运行时读取必须用边界包裹(或添加'use cache'),否则构建会报错shell-suspense-does-not-force-dynamic— 单独使用 Suspense 不会让同步工作变为动态shell-place-boundaries-low— 包裹动态叶节点,而非整个页面,让外壳尽可能完整
3. 使用 'use cache' 缓存
cache-use-cache-directive— 在函数、组件、页面、布局或文件级别标记静态/可缓存工作cache-keys-are-automatic— 参数和闭包会构成缓存键;将变化的输入作为参数传入cache-pass-runtime-values-as-props— 不能在缓存作用域内读取cookies()/headers();应将值传入cache-pass-through-children-and-actions— 将动态children和 Server Actions 原样传递给缓存组件cache-set-lifetime-and-tags—cacheLife控制 TTL,cacheTag支持按需失效cache-in-memory-not-durable-serverless— 内存缓存无法在无服务器环境中持久保存;请使用'use cache: remote'
4. 运行时 API 与非确定性
runtime-request-apis-force-a-boundary— 异步cookies/headers/searchParams/params会强制创建动态边界runtime-keep-param-routes-static—generateStaticParams可让[slug]路由保留在静态外壳中runtime-gate-nondeterminism-with-connection— 使用connection()限制Math.random/Date.now/crypto的调用,或缓存其值
5. 页面组合方案
compose-single-dynamic-hole— 基本模式:静态外壳 + 一个<Suspense>空洞compose-parallel-holes— 每个组件使用一个边界 → 并行流式传输,避免瀑布式加载compose-stream-to-client-with-use— 传递未等待的 Promise,并在客户端组件中使用use()解包compose-do-not-opt-out-the-shell— 不要为了消除边界错误而延迟整个应用
6. 表单、变更与向导
mutate-updatetag-vs-revalidatetag—updateTag(读写一致)与revalidateTag(tag, profile)(SWR)及refresh()mutate-wizard-url-driven-steps— 由 URL 驱动步骤 + 静态界面 +<Activity>保留字段内容
如何使用
遇到相应决策时,请阅读参考文件。每条规则都会指出其要纠正的错误默认做法,然后展示规范做法(仅当错误做法确实容易造成问题时,才会对比错误与正确做法)。如果你刚开始接触,请先阅读 setup- 开头的文件——其余内容都以“默认动态”的思维模型为前提。
- 章节定义 — 类别结构与排序
- 边界调试 — 使用
next build和 chrome-devtools-mcp(通过 mcporter)实证拆解静态/动态边界及加载过程;当 PPR 结果出乎意料或你正在排查blocking-route错误时,请使用 - 规则模板 — 用于添加新规则
- AGENTS.md — 自动生成的涵盖所有规则的目录
相关技能
nextjs— 更全面的 Next.js 16 App Router 最佳实践(缓存、服务端组件、路由、规范)opinionated-nextjs-patterns— 完整的观点鲜明的架构(数据层、变更操作、客户端边界),采用这些 PPR 模式react-fetch-cache-patterns— 面向数据密集型 React UI 的请求编排和客户端缓存
参考文件
| 文件 | 描述 |
|---|---|
| references/_sections.md | 类别定义和排序 |
| references/_debug-boundaries.md | 实证 CSR/SSR 边界与加载调试(next build + 通过 mcporter 使用 chrome-devtools-mcp) |
| assets/templates/_template.md | 新规则模板 |
| metadata.json | 版本和来源参考 |