增量静态再生 (ISR)
Next.js 允许您在构建站点后创建或更新静态页面。增量静态再生 (ISR) 使您能够按页面使用静态生成功能,而无需重新构建整个站点。通过 ISR,您可以在扩展到数百万页面的同时保留静态化的优势。
须知:目前
edge
运行时 与 ISR 不兼容,但您可以通过手动设置cache-control
标头来利用stale-while-revalidate
策略。
要使用 ISR,请在 getStaticProps
中添加 revalidate
属性:
当请求访问构建时预渲染的页面时,将首先显示缓存的页面。
- 在初始请求后的 10 秒内,所有对该页面的后续请求也都是缓存且即时响应的
- 10 秒窗口期过后,下一个请求仍会显示缓存的(过时)页面
- Next.js 会在后台触发页面重新生成
- 一旦页面成功生成,Next.js 将使缓存失效并显示更新后的页面。如果后台重新生成失败,旧页面将保持不变
当请求访问尚未生成的路径时,Next.js 会在第一次请求时进行服务端渲染。后续请求将从缓存中提供静态文件。Vercel 上的 ISR 会全局持久化缓存并处理回滚。
须知:检查您的上游数据提供商是否默认启用了缓存。您可能需要禁用缓存(例如设置
useCdn: false
),否则重新验证将无法获取新数据来更新 ISR 缓存。当端点返回Cache-Control
标头时,CDN 可能会对请求的端点进行缓存。
按需重新验证
如果您将 revalidate
时间设置为 60
,所有访问者将在一分钟内看到相同的生成版本。使缓存失效的唯一方式是等待一分钟后有人访问该页面。
从 v12.2.0
开始,Next.js 支持按需增量静态再生,可以手动清除特定页面的 Next.js 缓存。这在以下场景中更新站点更加方便:
- 无头 CMS 中的内容被创建或更新
- 电子商务元数据发生变化(价格、描述、类别、评论等)
在 getStaticProps
中,您不需要指定 revalidate
来使用按需重新验证。如果省略 revalidate
,Next.js 将使用默认值 false
(不重新验证),仅在调用 revalidate()
时按需重新验证页面。
须知:中间件 不会为按需 ISR 请求执行。相反,应在您想要重新验证的精确路径上调用
revalidate()
。例如,如果您有pages/blog/[slug].js
和从/post-1
重写到/blog/post-1
,您需要调用res.revalidate('/blog/post-1')
。
使用按需重新验证
首先,创建一个只有您的 Next.js 应用知道的密钥令牌。此密钥将用于防止未经授权访问重新验证 API 路由。您可以通过以下 URL 结构访问该路由(手动或通过 webhook):
接下来,将密钥作为环境变量添加到您的应用中。最后,创建重新验证 API 路由:
查看我们的演示以了解按需重新验证的实际应用并提供反馈。
在开发期间测试按需 ISR
当使用 next dev
本地运行时,getStaticProps
会在每个请求上调用。要验证您的按需 ISR 配置是否正确,您需要创建生产构建并启动生产服务器:
然后,您可以确认静态页面已成功重新验证。
错误处理和重新验证
如果在处理后台重新生成时 getStaticProps
内部出现错误,或者您手动抛出错误,将继续显示最后成功生成的页面。在下一个后续请求中,Next.js 将重试调用 getStaticProps
。
自托管 ISR
增量静态再生 (ISR) 在自托管 Next.js 站点上开箱即用,只需使用 next start
。
您可以在部署到容器编排系统如 Kubernetes 或 HashiCorp Nomad 时使用此方法。默认情况下,生成的资源将存储在每个 pod 的内存中。这意味着每个 pod 都有自己的一份静态文件副本。在请求命中特定 pod 之前,可能会显示过时数据。
为确保所有 pod 之间的一致性,您可以禁用内存缓存。这将告知 Next.js 服务器仅使用文件系统中由 ISR 生成的资源。
您可以在 Kubernetes pod(或类似设置)中使用共享网络挂载,以便在不同容器之间重用相同的文件系统缓存。通过共享相同的挂载点,包含 next/image
缓存的 .next
文件夹也将被共享和重用。
要禁用内存缓存,请在 next.config.js
文件中将 isrMemoryCacheSize
设置为 0
:
须知:根据共享挂载的配置方式,您可能需要考虑多个 pod 同时尝试更新缓存时的竞态条件。
版本历史
版本 | 变更 |
---|---|
v12.2.0 | 按需 ISR 功能稳定 |
v12.1.0 | 添加按需 ISR(测试版) |
v12.0.0 | 添加支持爬虫的 ISR 回退 |
v9.5.0 | 添加基础路径支持 |