在Next.js+next-redux-wrapper中用Promise.all优化请求是否可行?
问题
我在开发SEO页面时使用Next.js搭配next-redux-wrapper,原本在getServerSideProps中逐个等待dispatch执行:
export const getServerSideProps = wrapper.getServerSideProps( (store) => async ({ locale, query }) => { await store.dispatch(getInfo()) await store.dispatch(getCategories()) await store.dispatch(getTutorialLink()) await store.dispatch(getCatalog({ category_id: query.category_id ?? null })) return { props: { ...(await serverSideTranslations(locale)), }, } } )
所有动作均调用API,当前服务端是阻塞式拉取数据,需等待前一个请求完成再执行下一个。我想改成以下代码来提升加载速度:
export const getServerSideProps = wrapper.getServerSideProps( (store) => async ({ locale, query }) => { await Promise.all([ store.dispatch(getInfo()), store.dispatch(getCategories()), store.dispatch(getTutorialLink()), store.dispatch(getCatalog({ category_id: query.category_id ?? null })) ]) return { props: { ...(await serverSideTranslations(locale, ['draw'])), }, } } )
请问这种做法是否合理?
回答
这种做法完全合理,是优化服务端数据拉取性能的常规操作。
原写法串行执行每个dispatch对应的API请求,总耗时等于所有请求时间的总和;改用Promise.all后,这些请求会并行发起,总耗时基本等同于耗时最长的单个API请求时间,能显著缩短getServerSideProps的执行时长,提升页面加载速度。
需要注意几个细节:
- 确认API请求间无依赖关系:如果某个请求的参数依赖前一个请求的返回数据,就必须保持串行。从你的代码来看,
getCatalog仅使用query中的category_id,和其他请求无关联,所以可以安全并行。 - 异常处理:
Promise.all会在任意一个请求失败时直接抛出错误,导致整个数据拉取流程中断。如果部分请求失败不影响页面核心渲染,可以考虑使用Promise.allSettled并在后续处理失败情况;若这些数据均为页面渲染必需,保持Promise.all即可,因为任一请求失败页面都无法正常渲染。 - Redux状态更新:并行dispatch多个异步action时,Redux会按action完成的顺序更新状态,只要每个action对应的状态(比如
info、categories)相互独立,就不会出现状态冲突或覆盖问题。
综上,只要你的API请求之间没有依赖,这种并行改造是非常值得做的优化。
内容的提问来源于stack exchange,提问作者UKRman
相关产品推荐
相关产品推荐

