Next.js页面预渲染过程中的请求是否可以设置节流限制?
我正在开发一个由Next.js预渲染多个静态页面的网站。
我需要在getStaticPaths中发起大量API请求来确认后端存在的全部页面路径,除此之外每个页面还需至少发起一次API请求拉取实际数据,因此构建过程会在短时间内向后端发起大量并发请求,这似乎引发了问题。
目前我的后端似乎达到了某种阈值,会返回507 Insufficient Storage错误而非预期的API响应。
我推测是我使用的廉价共享主机无法在短时间内处理这么多请求,因此想了解Next.js是否提供节流机制,可以给后端留出缓冲空间。
我可以自行在getStaticPaths中为我可控的请求添加节流逻辑,但如果这还不够,我要如何为Next.js针对我返回的每个路径发起的请求设置节流?
显然还有很多其他方案可以解决这个问题,包括:
- 使用响应API请求时资源消耗更低的优质CMS
- 升级资源更充足的主机方案
- 减少预渲染页面数量,让访问量较低的页面在首次访问时由Next.js动态生成
但我的核心问题依然是:Next.js预渲染器发起的请求是否可以设置节流?
需要注意的是,该功能也可用于对接有严格速率限制的后端场景。
Next.js本身没有内置专门针对预渲染阶段请求的节流配置,但可以通过以下几种自定义方案实现节流控制,完全覆盖getStaticPaths和所有页面getStaticProps的请求场景:
1. 全局统一限制API请求并发数
这是最灵活、效果最好的方案,你可以用轻量并发控制库p-limit全局包装所有预渲染阶段的API请求,统一控制总并发数:
首先安装依赖:
npm install p-limit
然后创建全局的限流请求工具:
// utils/throttledFetch.js import pLimit from 'p-limit' // 这里的数字是总并发数,根据你的后端承受能力调整,廉价主机可以先设为2或3测试 const concurrencyLimit = pLimit(2) export const throttledFetch = async (url, options) => { // 所有请求都会被加入限流队列,超过并发数的请求会等待前面的请求完成再发起 return concurrencyLimit(async () => { const res = await fetch(url, options) // 可选:请求完成后加个短延迟,进一步降低请求密度 await new Promise(resolve => setTimeout(resolve, 100)) return res }) }
之后把你在getStaticPaths、getStaticProps中所有用到的原生fetch都替换成这个throttledFetch即可,全局所有预渲染请求的并发数就会被严格限制在你设定的阈值内。
2. 降低Next.js构建并行worker数
Next.js构建时默认会启用和CPU核心数对应的worker进程并行渲染页面,你可以手动降低worker数,减少同时执行的渲染任务,自然降低并发请求量:
构建时执行以下命令即可:
# 将worker数设为1,所有页面完全串行渲染,并发请求数最低 NEXTJS_WORKER_COUNT=1 npm run build
这个方案不需要修改业务代码,缺点是构建速度会变慢,适合页面数量不算特别多的场景。
3. App Router场景适配
如果你用的是Next.js 13+的App Router,逻辑和Pages Router一致,只要把所有服务端组件、generateStaticParams(对应Pages Router的getStaticPaths)里的请求都用上面的限流工具包装即可。
你可以根据自己的场景单独用某一种方案,也可以两种方案搭配使用:比如把并发数设为3,同时把worker数设为2,进一步降低后端压力。
内容的提问来源于stack exchange,提问作者Shawn

