为何多个fetch请求串行执行?如何优化Chrome下的性能?
问题描述
我尝试通过以下代码并行发起多个fetch请求:
fetch( `http://localhost/test-paralell-loading.php?r` ); fetch( `http://localhost/test-paralell-loading.php?r` ); fetch( `http://localhost/test-paralell-loading.php?r` );
但它们在Chrome中意外串行执行(截图显示请求依次发起),在Firefox中则正常并行。想问这是HTTP 1.1的限制吗?该如何解决并优化Chrome中的性能?
原因分析与解决方案
核心原因
这确实和HTTP/1.1的队头阻塞特性有关,再加上Chrome的连接复用策略共同导致:
- HTTP/1.1支持持久连接(Keep-Alive),但同一个TCP连接上的请求必须按顺序执行——前一个请求的响应返回后,才能发送下一个请求,这就是队头阻塞。
- Chrome对于完全相同的GET请求(URL、请求头均一致),会默认复用同一个TCP连接,导致三个请求只能串行执行;而Firefox针对这类场景采用了不同的连接调度策略,或者默认启用了HTTP/2,因此能并行处理。
优化方案
1. 升级到HTTP/2(推荐)
HTTP/2支持多路复用,同一个TCP连接可以同时传输多个请求和响应,彻底解决HTTP/1.1的队头阻塞问题。只要你的服务器支持HTTP/2(主流服务器如Nginx、Apache均可配置),Chrome会自动使用该协议,无需修改前端代码就能实现请求并行。
2. 给请求添加唯一标识
如果暂时无法升级HTTP/2,可以给每个请求的URL添加不同的查询参数,让浏览器判定为不同请求,从而创建新的TCP连接并发执行:
// 每个请求加随机数作为唯一标识 fetch(`http://localhost/test-paralell-loading.php?r=${Math.random()}`); fetch(`http://localhost/test-paralell-loading.php?r=${Math.random()}`); fetch(`http://localhost/test-paralell-loading.php?r=${Math.random()}`);
注意:需确保后端能忽略或正确处理这个随机参数。
3. 显式禁用连接复用(不推荐)
可以通过设置请求头Connection: close,让每个请求新建独立的TCP连接:
fetch(`http://localhost/test-paralell-loading.php?r`, { headers: { 'Connection': 'close' } });
这种方法虽能实现并发,但每个请求都要经历TCP三次握手,会增加额外性能开销,仅适合临时应急场景。
内容的提问来源于stack exchange,提问作者useless
相关产品推荐
相关产品推荐

