关于 nextjs-rendering
面向开发者的 Next.js 渲染指导技能,涵盖渲染模式选择,以及流式传输、Suspense 和缓存组件的配置。
主要功能
- 01比较静态与动态渲染
- 02说明异步 API 的模式判定
- 03使用 Suspense 配置流式传输
- 04解释 ISR 回退行为
- 05组合缓存与动态页面区块
适用场景
- 01为路由选择 SSG 或 ISR
- 02规划动态页面流式传输
- 03排查页面为何采用动态渲染
- 04缓存开销较大的页面组件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ goncy/ skills --skill nextjs-rendering安装后在 Claude Code 中输入/nextjs-rendering确认已加载。
详细介绍
Next.js 渲染
关于 Next.js 渲染模式、流式传输行为,以及静态与动态页面生成的专家指南。
静态渲染与动态渲染
Next.js 有两种基本的渲染类型:静态和动态。
静态渲染:
- 页面在构建时生成,并上传到 CDN
- 请求时不会进行计算
- 资源会在全球范围内复制到边缘节点
- 响应速度更快(无需计算,缓存位置靠近用户)
- 即使源站区域宕机,仍然可用
动态渲染:
- 页面按需在配置的区域执行
- 请求时需要进行计算
- 如果该区域不可用,服务也会中断
- 当内容无法在构建时确定时,这是必需的
SSG(静态站点生成)和 ISR(增量静态再生成)底层使用的是同一种机制,唯一的区别在于:是预先生成所有路径,还是按需增量生成。
确定渲染模式:异步动态 API
Next.js 使用异步动态 API来确定页面是静态还是动态。框架会执行一次前瞻性渲染,以检测哪些内容可以同步解析,哪些需要异步解析。
微任务测试:
- Next.js 执行一次初始“预热渲染”,以查找缓存实例并填充缓存
- 接着执行第二次渲染,只运行一个 tick,然后中止
- 能在该微任务内解析的内容会被视为“即时”内容,因此可以静态渲染
- 无法在一个 tick 内解析的内容会被视为动态内容
params 的特殊情况:
使用 params 的路由可以静态渲染,因为 generateStaticParams 会针对每个条目调用一次路由。由于这些参数在构建时已知,因此可以即时解析。
// Static: params from generateStaticParams resolve instantly
export async function generateStaticParams() {
return [{ id: '1' }, { id: '2' }];
}
export default async function Page({ params }: { params: { id: string } }) {
// params.id is instant - this page can be static
}
流式传输与 Suspense 边界
**只有动态渲染才会启用流式传输。**静态内容不会流式传输,因为它不涉及计算——完整的 HTML 会由 CDN 提供。
文档级 Suspense 要求: 如需启用流式传输并显示加载骨架屏,请在 HTML 文档外层包裹一个空的 Suspense 边界。如果边界外没有文档包装层,就没有内容可以流式传输——框架需要先发送外层框架,同时加载内部内容。
// Enable streaming with document shell
<Suspense fallback={null}>
<html>
<body>
<Suspense fallback={<Skeleton />}>
<SlowComponent />
</Suspense>
</body>
</html>
</Suspense>
ISR 与 Suspense 回退内容: 生成 ISR 路径时,不会显示 Suspense 边界的回退内容。由于 ISR 生成发生在构建时或首次请求时(静态生成),因此不会进行流式传输——完整页面会在提供之前生成。
缓存组件(use cache)
缓存组件可以在同一页面中组合静态与动态渲染,但页面本身仍然有自己的渲染模式。
将 use cache 应用于页面组件:
在页面或页面的主组件中添加 use cache 后,页面会生成静态输出,该输出:
- 会被缓存(静态)
- 不会进行流式传输
- 不会包含“空洞”(Suspense 边界)
动态页面中的缓存组件:
即使对单个组件使用 use cache,整个页面仍然是静态或动态渲染。缓存组件提供了细粒度控制——可在动态页面中使用静态缓存区块,也可在静态页面中使用动态区块。
// Page-level cache: produces static output
'use cache';
export default async function Page() {
// Entire page is static, no streaming
}
// Component-level cache: can mix static/dynamic
export default async function Page() {
return (
<>
<StaticCachedSection /> {/* has 'use cache' */}
<DynamicSection /> {/* no cache directive */}
</>
);
}
渲染工作流
使用 Next.js 渲染时:
- 确定页面是否可以静态渲染(所有数据都能在构建时获取)
- 如果可以静态渲染,决定使用完整 SSG(所有路径)还是 ISR(增量生成)
- 如果必须动态渲染,规划用于流式传输的 Suspense 边界
- 如果要通过流式传输显示骨架屏,添加文档级 Suspense 包装层
- 在动态页面中使用
use cache,对开销较大的组件进行细粒度缓存 - 请记住:只有动态渲染支持流式传输,静态渲染和 ISR 均不支持