恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
同域并发连接数限制:前端性能优化必知的浏览器机制
首页
资讯中心
/
同域并发连接数限制:前端性能优化必知的浏览器机制
同域并发连接数限制:前端性能优化必知的浏览器机制
发布时间:2026/9/28 5:20:44
上周帮一个前端朋友排查商品详情页加载慢的问题。页面本身不到 2MB后端接口响应也都在几十毫秒内但手机端打开要 4 秒以上。我打开 DevTools 的 Network 面板一眼就发现问题四十多个图片请求绝大多数状态都是 Waitings点开 Timing 一看大量时间花在 Queueing 和 Stalled 上TTFB 却短得离谱。这不是服务器慢是浏览器对同一个域名同域下的网络请求并发连接数限制把我们实实在在卡住了。浏览器为了不让一个域名被请求淹没同时也在保护客户端自身的资源会给“同一个域名同域”下同时存在的网络请求连接数量设一个上限。HTTP/1.1 时代主流桌面浏览器的默认值基本是 6超过 6 个请求必须排队等待直到某条连接空闲。这个限制对图片多、接口多、静态资源碎片化的站点影响特别大。这篇文章我会把限制的来龙去脉、不同浏览器的具体表现、HTTP/2 怎么破局以及域名分片这类经典方案的原理和代价讲清楚。无论你是做前端、做性能优化还是正被线上加载问题折磨都值得看完。1. 一次“排队”事故同域并发连接数限制是怎么暴露的1.1 当所有请求都卡在 Queueing 时先怀疑这个限制回到那个商品详情页的案例。把 Network 面板按时间排序后可以清楚看到前 6 张图片几乎是同时开始下载后面的请求全部变成灰色等待状态排队时间从几十毫秒到几百毫秒不等。网络状况再差一点排队能到秒级。我点开一个排在后面的图片请求Timing 面板里的数据是这样的Queueing 占 800msStalled 占 120ms而 Connection、Request sent、Waiting 都很短。这说明请求压根没出浏览器不是服务器不响应是浏览器自己不让它“上车”。判断这个现象有一个很粗暴的方法同域资源数量明显超过 6请求又是密集发起的同时每个请求的 TTFB 都很快那么大概率就是撞上了并发连接数限制。此时你换任何一个浏览器只要还在 HTTP/1.1 下得到的结果都类似。先把怀疑目标放在浏览器这里能省下你排查服务器配置、DNS 解析、网络策略的一大堆时间。我见过太多团队在这个问题上反复查服务器最后才发现是浏览器排队。1.2 6 连接现代浏览器给出的经验值为什么是 6这得从 HTTP/1.1 说起。HTTP/1.1 时代浏览器与服务器之间会保持若干个持久连接Keep-Alive请求在连接上串行发送。浏览器设置一个“同时最多能有几个活动连接”的上限超出上限的请求就排队。早期 IE6/7 是 2 个后来普遍放宽到 4 个再到 6 个。今天的 Chrome、Firefox、Safari、Edge 在 HTTP/1.1 下对每个主机名基本都是 6 个连接。移动端 WebView 和桌面端策略类似部分定制内核可能会稍高或稍低但 6 是出现频率最高的默认值。注意这个上限是客户端侧的服务器端没法直接改掉它。这里有个细节很多人忽略这个“同域”是按主机名域名 端口 协议来计算的不是按服务器 IP。两个完全不同的域名即使解析到同一台服务器的同一个 IP浏览器也会分别给它们分配独立的连接池各自享受 6 个并发连接。这个特性正是后面域名分片方案能成立的基础记住它第四节还会用上。2. 为什么会存在这道“卡”TCP 握手、Keep-Alive 与服务器保护2.1 一个请求最贵的不是流量而是握手与慢启动很多人觉得网络请求慢主要因为带宽不够但在页面加载场景里真正的成本往往在连接建立阶段。每建立一个 TCP 连接要经历三次握手在普通无线网络里一次握手大概要 50~100ms叠加 TLS 握手之后HTTPS 场景下首次建连甚至要 200ms 以上。连接建立之后还有 TCP 慢启动拥塞窗口从小值逐渐扩大最早几个包传输速度极其有限。如果每个请求都新建连接一个网页有 50 个资源就要经历 50 次建连开销时间浪费非常惊人。HTTP/1.1 的 Keep-Alive 解决了“反复建连”的问题连接可以复用请求在一条连接上串行跑。但串行意味着后一个请求必须等前一个请求完成所以浏览器才需要同时开多条连接来保证并行度。这里的“6 个连接”本质上是在“连接复用”和“并行请求”之间取平衡。连接太少并行度不够连接太多每条连接分不到足够的带宽。6 是浏览器厂商在实践中试出来的经验值不是什么数学上的最优解。2.2 RFC 的“2 连接”建议为何被浏览器悄悄放宽很多文档会引用一个老古董RFC 2616 建议单个客户端与同一服务器保持的连接不要超过 2 个。这是 1999 年的规范当时服务器资源紧张、网络带宽有限2 连接是为了防止客户端把服务器拖垮。但 2 连接的体验太糟糕一个页面几十个资源会载入得极其缓慢。于是浏览器厂商都“默契”地把上限放宽到了 6本质是向用户体验妥协。今天的服务器早就不怕一个浏览器开 6 条连接真正怕的是成千上万个浏览器因为页面资源碎片化同时发起洪水般的请求。还有一个人们容易忽略的角度连接数上限保护的不只是服务器也是客户端本身。每条 TCP 连接都要占用文件描述符、缓冲区、内存网络栈要为每条连接单独维护拥塞状态。如果浏览器允许一个页面无限并发请求普通电脑可能直接卡顿甚至崩溃。现在你打开系统自带的任务管理器看 Chrome 的进程数量就能直观理解浏览器为并发付出了多少资源。2.3 连接不是越多越好拥塞窗口被瓜分多说一点“为什么不能把并发连接数改成 100”。假设网络带宽固定6 条 TCP 连接各自维护自己的拥塞窗口它们会同时慢启动、抢占带宽、相互造成抖动。结果是每个连接都处于“还没跑满带宽就已经传完了”的状态整体效率反而比少数几条稳定连接更差。这就是“并行太多反而慢”的真实原因。所以即便浏览器允许你通过 flags 调整并发数普通场景也不建议为了硬扛资源数去盲目调高它。正确的方向永远是减少请求、合并资源、升级协议。3. 浏览器限制值全景与 HTTP/2 的破局方式3.1 主流桌面浏览器 HTTP/1.1 并发限制一览我整理了一下现代浏览器在 HTTP/1.1 下对同一域名的并发连接限制值方便大家心里有底浏览器HTTP/1.1 下每主机并发连接备注Chrome / Edge6桌面与 Android WebView 基本一致Firefox6老版本曾为 2现代版本均为 6SafarimacOS/iOS6部分版本表现保守IE 系列2~6IE6/7 为 2IE8 为 6这个数值是实践经验值不是死规矩不同版本间会有小幅差异。排查问题不需要背死数字记住“6 左右”就够了。真正要理解的是浏览器把“连接”当成有限资源使用的基本逻辑连接有限请求很多排队现象必然出现在性能面板上。另外这个限制不是说浏览器必须凑满 6 个连接才发请求只有 2 个请求时连接数量低于上限浏览器不会刻意把连接填满。瓶颈永远出现在“请求数量大于连接池容量”的时候。3.2 HTTP/2 如何用一条连接扛住几十个请求HTTP/2 出来后规则变了。它引入了多路复用一条 TCP 连接上可以同时交织传输多个请求和响应每个请求被拆成帧独立编解码。浏览器不再需要为每个并行请求建立新连接更不需要用 6 条连接去做并行每个域名只需要维护一条 HTTP/2 连接所有请求在这条连接上以“流”的形式并行传输。于是“同域并发连接数限制”这个问题在 HTTP/2 下基本消失。举个直观的例子HTTP/1.1 下页面需要加载 20 张图片浏览器会开 6 条连接每张图片一组一组排队后面大量请求只能等待。HTTP/2 下浏览器在一条连接上同时创建几十个流每张图片的数据帧交叉传输理论上所有图片几乎同时开始下载。效果上大量同域资源的加载时间会显著缩短在高延迟网络下尤其明显因为它省掉了大量排队等待。可以这样理解HTTP/1.1 的 6 条连接像 6 条小水管HTTP/2 的一条连接像一根大水管里面可以同时输送很多股水流。实际部署上HTTP/2 几乎都跑在 TLS 之上。只要站点采用 HTTPS并在服务器开启 ALPN 协商浏览器就会在握手时优先选择 HTTP/2。现在主流 CDN、云负载均衡、Nginx 都默认支持 h2迁移成本并没有想象中那么高。3.3 给 Nginx 启用 HTTP/2从小站直接受益如果你的站点还在 HTTP/1.1并且恰好用 Nginx 做边缘开启 HTTP/2 非常简单。下面是一段最小配置server { listen 443 ssl http2; server_name example.com; ssl_certificate /your/path/fullchain.pem; ssl_certificate_key /your/path/privkey.pem; # 其余配置保持不变 }注意listen行末尾的http2参数它告诉 Nginx 启用 HTTP/2 协议。浏览器通过 TLS 握手时的 ALPN 协商知道服务器支持 h2就会自动使用 HTTP/2同域并发限制的排队问题会大幅度缓解。如果你的 Nginx 版本较老不支持http2参数建议升级到 1.25.1 以上版本新版 Nginx 中 http2 指令的写法已经调整具体以你所用版本的官方文档为准。升级之后你会发现之前精心设计的多子域静态资源体系反而变成了一件需要收拾的旧债。4. 绕过同域限制的经典方案域名分片与替代优化4.1 域名分片的原理和落地步骤HTTP/1.1 时代如果同域并发限制卡住了页面工程师们发明了“域名分片”。原理很朴素既然浏览器按主机名分别计算连接池那把静态资源拆到几个子域名下比如 static1.example.com、static2.example.com、static3.example.com每个子域名独立享受 6 个并发连接。页面需要加载 30 张图拆到 3 个子域后理论上可以同时建立 18 条连接排队时间大幅下降。落地步骤大致是在 DNS 上把 static1、static2、static3 都解析到同一台或同一组资源服务器。构建时把资源 URL 按一定规律分散到不同子域或者用不同的桶名。确保这些子域不携带业务 Cookie减少请求头体积资源请求通过 img、script、link 标签天然跨域不需要额外处理。业务接口不要放到分片域名里接口与静态资源域名分离避免 CORS 和 Cookie 的连锁问题。这套方案在 2010 年前后非常流行大型门户网站动辄用三四个静态域名效果立竿见影。但它不是免费的每增加一个域名就要增加一次 DNS 解析、增加一条或多条 TCP 连接、增加 TLS 握手成本。如果资源总量不大分片带来的额外握手开销可能超过排队节省的时间变成负优化。域名分片本质上是“用更多连接换并行度”必须算清楚成本再去拆。4.2 为什么 HTTP/2 时代域名分片反而拖后腿HTTP/2 普及后主流性能优化建议开始反着来把子域合并回去尽量收敛到一个域名。原因有两点。第一HTTP/2 多路复用已经让你在一个域名下获得极高并发不再需要子域扩充连接池。第二域名分片会让客户端为每个子域各自维护一条 HTTP/2 连接等于把一根大水管拆成几根独立水管TCP 拥塞控制效果被削弱连接之间的带宽竞争还会拖长加载时间。原本为了并行而拆开的资源现在反而因为并行度下降和握手开销增加而变慢。所以判断标准很简单站点已经是 HTTP/2就不要再用域名分片还在 HTTP/1.1 且暂时无法升级那分片仍有适用场景。CDN 提供的加速域名本质上也是“另一个域”用 CDN 时天然把资源放到了新的主机名下但要意识到这是为了内容分发不是为了绕开 6 连接限制。把 CDN 域名和域名分片混为一谈容易在优化时做出错误决策。4.3 比“拆域名”更值得做的几件事与其纠结怎么扩并发连接不如先问一句为什么一个页面要同时发起这么多请求把请求数量降下来什么限制都不是问题。实践中我通常会优先做这几件事合并资源小 JS/CSS 文件合并成一个图片用雪碧图减少请求总数。懒加载非首屏资源图片加loadinglazyJS 按路由拆分让首屏并发请求数量降下来。预连接关键域名在head里给即将用到的资源域名加link relpreconnect hrefhttps://cdn.example.com提前建立连接池节省后续请求的排队和握手时间。服务端合理设置 Keep-Alive 超时如果服务器频繁关闭空闲连接浏览器会不断新建连接重新占用并发名额增加排队和握手成本。接口聚合把多个小接口合并成大接口减少同域并发请求数。这些方案不依赖 HTTP 版本也不需要动域名结构属于更稳健的长期优化。域名分片只是不得已时的“应急方案”不是架构目标。5. 实战排查与避坑判断并发瓶颈别乱甩锅给服务器5.1 用 DevTools 的 Timing 面板找出真正瓶颈当你怀疑是并发连接数限制时不要靠猜用 DevTools 确认。Chrome 的 Network 面板可以这样操作刷新页面观察同域资源是否出现明显“一批一批”加载的模式然后点开排在后面的请求看 Timing 标签页。如果 Queueing 和 Stalled 占据了大半时间而 TTFB 很短基本就是连接排队。再做一个对照实验临时把页面放到一个支持 HTTP/2 的静态服务器上或者借助在线 h2 测试环境如果排队现象明显消失那就实锤了。另外一个容易混淆的点Queueing 不完全是并发限制引起的。浏览器还会因为资源优先级调度主动让某些请求排队例如没有拿到 CSSOM 的同步脚本会阻塞后续资源发现高优先级关键请求会插队到低优先级之前。所以看 Timing 的同时建议打开 Network 面板的 Priority 列确认被排队的请求优先级是不是确实低于正在传输的请求。如果是低优先级请求卡住高优先级请求正常这属于浏览器加载策略问题调整资源优先级比调整域名结构更有效。5.2 同域边界、端口协议、移动端 WebView 的坑关于“同域”的边界有几个常见误区。第一协议不同会分开计算http://example.com和https://example.com会被浏览器视为不同的主机连接池各自独立。但生产环境里绝不能为了白捡 6 个并发而故意让资源走 HTTP那会引入混合内容问题属于因小失大。第二端口不同也会分开计算比如 80 和 8080 各自算 6 连接但不同端口带来的跨域麻烦更多落地不现实。第三子域名与根域名是不同主机限制分开计算这正是域名分片的基础但即使把 a.example.com 和 b.example.com 指向同一台服务器浏览器依旧各自计算不会自动合并连接池。移动端的情况要更敏感。iOS Safari 和 Android WebView 在 HTTP/1.1 下同样有 6 连接限制弱网环境下 RTT 高排队时间会被放大得很严重。做小程序开发时也会遇到类似现象同一个域名下并发请求一多长尾请求就一直 Pending一旦宿主环境设置了较短的超时时间就会出现集中请求失败。尤其是部分 iOS 机型这个现象被不少人误判为“服务器挂了”。虽然网络失败率高不一定是并发限制唯一原因但排查时一定把它纳入怀疑列表否则很容易绕弯路。5.3 我的几点经验与建议到这里关于同域并发连接数限制的核心内容基本讲透了。我个人在实际项目里的判断顺序是先确认站点是否已经启用 HTTP/2没有就先迁过去迁完之后看请求总数和资源体积再决定做合并、懒加载还是预连接只有确实无法规避服务器压力且大量同域小资源需要并发加载时才考虑用子域分片而且分片只用于静态资源绝不放业务接口。还有一点想专门提醒不要试图修改浏览器内置的并发连接数上限来解决问题。这个数字是浏览器网络栈综合权衡后的结果强行调高或许能换来局部加载速度提升但会放大服务器压力而且因为连接之间抢占带宽整体性能未必变好。真正有效的优化永远是让请求更少、更短、更合理地排队而不是把队列直接拆没。我踩过几次坑之后的体会是理解浏览器为什么要设限比研究怎么绕过限制更有价值。