HTTP/2多路复用由协议层自动启用,HTML不需启用但写法直接影响其效能:避免子域名分片、统一主域名、善用preload抢占通道、禁用同步脚本阻塞,验证需看Protocol为h2且同域名请求共用Connection ID。

HTTP/2 多路复用本身不需要 HTML “启用”,它由服务器和客户端协商决定;但 HTML 的写法会直接决定你能不能让多路复用真正并发加载资源——关键不在“怎么开”,而在“别关掉它”。
为什么把资源分到多个子域名反而破坏多路复用
这是最常踩的坑:沿用 HTTP/1.1 时代的“域名分片”(如 static1.example.com、static2.example.com),以为能提升并发,结果在 HTTP/2 下彻底失效。
- 每个子域名需独立 TLS 握手 +
SETTINGS帧协商,增加 RTT 延迟 - 浏览器无法跨域名复用 TCP 连接,
main.js和logo.png被打散到不同连接,流 ID 不共享,优先级调度失效 - 证书 SNI 差异或 CDN 配置不一致时,连接甚至被强制断开重连
- 实测显示:单域名 + HTTP/2 通常比 4 子域名 + HTTP/1.1 快 15–30%
解决方法很简单:所有静态资源统一指向主域名,例如全部用 https://example.com/assets/ 开头,不拆。
用 link rel="preload" 抢占复用通道带宽
浏览器解析 HTML 是线性的,遇到 <script src="app.js"> 才发起请求——这中间可能有几十毫秒空窗,复用连接闲着。而 preload 能在解析早期就触发请求,填满流。
立即学习“前端免费学习笔记(深入)”;
-
as属性必须写,否则浏览器无法设置正确Accept头和缓存策略,例如:<link rel="preload" href="/styles.css" as="style"> - 只 preload 关键首屏资源(如 above-the-fold CSS、主 JS、核心图片),非关键资源(页脚广告、分析脚本)会挤占带宽
-
preload不阻塞 HTML 解析,但会提升该资源在复用流中的调度优先级 - 不要指望
preload自动执行——<script>仍需显式引入才能运行
避免同步脚本阻塞后续流创建时机
即使启用了 HTTP/2,一个没加 async 或 defer 的外部 <script> 仍会暂停 HTML 解析,导致后续 <img>、<link> 标签无法及时触发请求——复用连接有空闲,但浏览器“不敢发”。
- 对非首屏依赖的 JS,优先用
async(无执行顺序保证)或defer(按文档顺序执行) - 如果必须同步加载(如某些初始化逻辑),考虑将依赖打包进同一文件,减少请求数而非靠多路复用来掩盖阻塞
- 注意:多路复用解决的是传输层队头阻塞,不是执行层阻塞;
document.write()或未声明依赖的import依然会报ReferenceError
验证是否真正在用多路复用,别信瀑布图
Chrome DevTools 的 Network 面板里看到一堆请求“排队”或“pending”,不等于多路复用失效——那只是 UI 抽象。真实判断只看两点:
- 右键表头 → 勾选
Protocol列,所有请求必须显示为h2(不是http/1.1或空白) - 同域名下 ≥2 个请求(比如
main.css和hero.jpg)的Connection ID必须完全相同 - 如果 Protocol 显示
h2但 Connection ID 不同,说明 CDN 或反向代理做了协议降级(例如边缘节点是 HTTP/2,但回源走 HTTP/1.1)
真正容易被忽略的是:多路复用生效的前提是服务端支持且未被中间设备拦截,而 HTML 本身只是“调用方”——它不控制流,但一写错,就等于把高速路修成了单行道。



















