浏览器网络限速时fetch与JSON解析耗时差异的原因探究
关于Chrome与Firefox中Fetch API性能差异的解析
核心问题:两个await分别等待什么?
await fetch(...):仅等待响应头返回,而非完整响应体。当服务器发送完响应头(HTTP状态码、Content-Type等)后,Promise就会resolve,此时响应体可能还在传输过程中。await response.json():等待完整响应体下载完成,然后将其解析为JSON对象。这一步包含两个动作:下载剩余的响应体数据,以及执行JSON.parse()解析。
Chrome与Firefox的Fetch实现差异及行为原因
Chrome(Chromium内核)的表现
当限制网络速度时,res1(fetch的耗时)增加,res2保持不变:
- Chromium的Fetch实现中,
fetch()的Promise会在响应头到达后立即resolve,但响应体的下载会在后台继续进行。当你调用response.json()时,大部分响应体可能已经在后台下载完成了,所以解析耗时基本不受限速影响,res2稳定。 - 限速主要影响响应头的传输时间(后续后台下载响应体的时间不占用
await fetch()的等待时间),因此res1会随限速严格增加。
Firefox的表现
限速时res1不变、res2增加,且整体耗时更小:
- Firefox的Fetch实现采用了不同的调度策略:它会在
fetch()的Promise resolve前,提前开始下载响应体,甚至可能在响应头返回时,响应体已经部分或全部下载完成。但Firefox会严格遵循标准,让fetch()的Promise在响应头到达后立即resolve;当调用response.json()时,如果响应体还没下载完,就需要等待剩余部分下载,此时限速的影响就体现在res2上。 - 整体耗时更小的原因可能是Firefox的后台下载调度更高效,或是对本地
localhost请求有特殊优化,减少了不必要的等待开销。
是否与DevTools网络限速方式有关?
是的,两者的限速实现细节存在差异:
- Chromium的DevTools限速会严格控制所有网络请求的传输速率,包括响应头和响应体,而
fetch()的Promise等待阶段仅关注响应头的到达时间,所以限速直接体现在res1。 - Firefox的DevTools限速可能对响应体的下载调度有不同处理,比如允许响应体在
fetch()resolve前提前下载,但统计response.json()的等待时间时,会把未完成的下载时间算进去,导致res2增加。另外,Firefox对本地localhost请求的限速可能有特殊优化,使得整体耗时更低。
总结
两者的行为差异源于:
- Fetch API在响应体下载调度上的实现策略不同;
- DevTools网络限速的具体机制差异;
- 对本地请求的优化程度不同。
但两者都符合Fetch API的标准:await fetch()确实只等待响应头,response.json()等待响应体下载并解析。
内容的提问来源于stack exchange,提问作者Dorus
相关产品推荐
相关产品推荐

