HTTP/2下域名分片反而拖慢性能,因其原生多路复用可单连接并行处理数十个流,拆子域导致多次TLS握手、优先级调度割裂及压缩状态不共享,实测比同域名HTTP/2慢15–30%。

域名分片在 HTTP/1.1 下确实能提升并发请求数,但效果取决于是否满足 DNS、证书、Cookie 和数量四个硬性条件;在 HTTP/2 环境下它反而会降低性能,不是“加子域就提速”,而是“错配协议就拖慢”。
为什么 static1.example.com 和 static2.example.com 能突破 6 连接限制
浏览器对「同源」(协议+域名+端口)有明确的 TCP 连接池上限,主流是 6~8 个。所有请求发往 https://static.example.com 时,第 7 个 fetch() 或第 9 张 <img> 就必须排队等待空闲连接。
换成 https://static1.example.com 和 https://static2.example.com 后,浏览器判定为两个不同源,各自维护一套 6 连接池——理论并发能力翻倍。但这仅在以下条件下成立:
- DNS 必须能解析全部子域名(
static1.example.com、static2.example.com等需返回相同 IP 或 CDN CNAME) - TLS 证书必须覆盖所有子域(推荐通配符
*.example.com;否则 Safari/iOS 可能直接拒绝连接) - 静态资源域名不能携带 Cookie(避免
Domain=example.com的 Cookie 自动附带,增大请求头、延长传输) - 子域数量控制在 3~5 个;超过后 Chrome 总 socket 数(约 256)可能触顶,反而引发系统级排队
HTTP/2 下用子域名散列反而拖慢加载
HTTP/2 原生支持多路复用:单个 TCP 连接上可并行处理几十个流(stream),且共享优先级调度、头部压缩和连接状态。此时再拆子域,等于主动放弃复用优势。
立即学习“前端免费学习笔记(深入)”;
常见错误现象包括:
使用 Puppeteer + Chrome 将 HTML 渲染为中文 PDF,自动处理图表等待、Tab 展开、动画、测高、白边消除、防分页,适用于看板、报表、网页和交互图表转 PDF。
- Network 面板里多个
static*.example.com请求显示 Protocol 列为h2,但 Connection ID 各不相同 → 多次 TLS 握手 + SETTINGS 协商,RTT 增加 - 关键 CSS 和首屏图片被分到不同子域 → 浏览器无法统一调度流优先级,
logo.png可能比main.css先完成,导致 FOUC - CDN 配置未对齐(如
static1开了 Brotli 压缩,static2没开)→ 实际传输效率不一致,放大抖动
实测结论:同一域名 + HTTP/2 通常比 4 子域 + HTTP/1.1 快 15–30%,尤其在高延迟链路上更明显。
怎么判断当前该不该用子域名散列
不靠经验猜,直接看 Chrome DevTools 的 Network 标签页:
- 检查任意一个静态资源(如
vendor.js)的 Protocol 列:若显示h2或h3,说明已启用 HTTP/2+,应停用子域名散列,全部资源回归主域名(如https://example.com/assets/) - 若 Protocol 显示
http/1.1,再确认服务端是否真不支持 HTTP/2(有些 Nginx 配置漏了http2参数,或 CDN 未开启) - 用
curl -I --http2 https://example.com验证协议协商结果;返回失败则说明服务端未就绪
注意:navigator.connection.effectiveType 和 rtt 是客户端网络质量指标,和是否启用域名分片无关——它只影响你该发几个请求,而不是该不该换域名。
HTML 中写法决定分片是否真正生效
光改 URL 域名不够,浏览器预加载机制是否触发,取决于标签位置和写法:
-
<link rel="dns-prefetch" href="//static1.example.com">和<link rel="dns-prefetch" href="//static2.example.com">必须放在<head>最前面,否则 DNS 解析滞后,首图仍要等 -
<img src="https://static1.example.com/a.jpg">必须是 HTML 直接写出,不能靠 JS 拼接后innerHTML注入,否则错过 parser blocking 时机 - CSS/JS 的
src和href属性值必须显式含子域名;用 Webpack 的publicPath或 Vite 的base配置生成,别靠运行时环境变量拼接 - 禁止跨子域使用
localStorage或IndexedDB名称复用——它们仍按完整域名隔离,逻辑上误以为“同源”会导致读不到数据
真正起效的分片,是 DNS、TLS、HTTP、HTML 四层全部对齐的结果;任何一层断掉,都只是徒增管理成本。


















