为什么 HTTP/2 相比 HTTP/1.1 更快?(多路复用、头部压缩等)
HTTP/2 相比 HTTP/1.1 更快,主要是因为它解决了 HTTP/1.1 在传输效率和并发处理上的核心缺陷。HTTP/2 的核心改进是引入了二进制分帧层(Binary Framing Layer),这使得它能够实现多路复用、头部压缩等关键特性。
以下是 HTTP/2 变快的核心原因详解:
1. 多路复用 (Multiplexing) —— 最核心的提升
这是 HTTP/2 性能提升最大的因素,它解决了 HTTP/1.1 的队头阻塞(Head-of-Line Blocking)问题。
- HTTP/1.1 的问题:
- 在 HTTP/1.1 中,浏览器通常对同一个域名只能开启有限数量的 TCP 连接(通常是 6 个)。
- 在同一个 TCP 连接中,请求是串行的。必须等请求 A 响应回来后,才能发送请求 B。如果请求 A 处理很慢(比如服务端查数据库卡住了),请求 B 就会被阻塞。这就是“队头阻塞”。
- HTTP/2 的解决方案:
- 单一长连接: 整个页面加载只需要建立一个 TCP 连接。
- 并发传输: HTTP/2 将请求和响应数据分解为独立的帧(Frame),这些帧乱序发送,然后在接收端根据流 ID(Stream ID)重新组装。
- 效果: 多个请求(CSS、JS、图片)可以在同一个连接上并行传输,互不干扰。请求 A 慢了,不会影响请求 B 的传输。
2. 头部压缩 (Header Compression - HPACK)
现代网页通常包含数十个甚至上百个请求,HTTP/1.1 的头部(Header)冗余非常严重。
- HTTP/1.1 的问题:
- HTTP 是无状态的,所以每个请求都必须携带完整的 Header(如
User-Agent,Cookie,Referer等)。 - 这些 Header 往往是重复的,且是以纯文本传输。对于小文件(如小图标、API 数据),Header 的大小甚至可能超过 Body 的大小,浪费带宽。
- HTTP 是无状态的,所以每个请求都必须携带完整的 Header(如
- HTTP/2 的解决方案 (HPACK 算法):
- 静态字典: 客户端和服务端都维护一份常见的 Header 列表(如
method: GET),传输时只需发送索引号(比如用2代表method: GET),只需 1 个字节。 - 动态字典: 维护一份当前连接中已经发送过的 Header 列表。如果
Cookie在第一个请求发过了,后续请求只需发送“同上”的指令,或者只发送差异部分。 - 霍夫曼编码 (Huffman Coding): 对 Header 的键值对进行哈夫曼编码压缩,进一步减小体积。
- 效果: 头部体积大幅缩小(通常能减少 90% 以上),显著降低了延迟。
- 静态字典: 客户端和服务端都维护一份常见的 Header 列表(如
3. 二进制分帧 (Binary Framing)
HTTP/2 的所有性能增强都建立在这个基础之上。
- HTTP/1.1 的问题:
- HTTP/1.1 是文本协议。文本协议对人类友好(可读),但对机器解析来说效率较低,且容易出现歧义(比如处理空格、换行符)。
- HTTP/2 的解决方案:
- HTTP/2 是二进制协议。它将数据解析为更小的消息和帧,并采用二进制编码。
- 效果:
- 解析更快: 机器解析二进制流比解析文本快得多。
- 更健壮: 减少了文本解析带来的错误。
- 更紧凑: 二进制传输本身就比文本更节省空间。
4. 服务端推送 (Server Push)
- HTTP/1.1 的流程: 浏览器请求
index.html-> 服务器返回 HTML -> 浏览器解析 HTML 发现需要style.css-> 浏览器请求style.css-> 服务器返回 CSS。这里有一个往返延迟(RTT)。 - HTTP/2 的解决方案:
- 服务器在返回
index.html的同时,可以“猜到”客户端需要style.css,于是主动把style.css一并推送到客户端的缓存中。 - 当浏览器解析 HTML 想要请求 CSS 时,发现缓存里已经有了,直接使用,无需网络请求。
- 注:虽然这是个好特性,但在实际工程中配置复杂且存在缓存一致性问题,目前 Chrome 等浏览器已逐渐不再推荐使用 Push,转而使用
103 Early Hints,但它依然是 H2 的一项技术优势。
- 服务器在返回
5. 请求优先级 (Stream Prioritization)
由于所有请求都在一个连接中复用,如果不加控制,可能会导致重要的资源(如 CSS、关键 JS)被不重要的资源(如底部的图片)抢占带宽。
- HTTP/2 的解决方案:
- 客户端可以在发送请求时,给每个流(Stream)标记优先级和依赖关系。
- 服务器可以根据这些信息,优先处理和发送高优先级的资源(比如先发 CSS 让页面渲染出来,再发图片)。
总结:为什么更快?
| 特性 | HTTP/1.1 | HTTP/2 | 性能影响 |
|---|---|---|---|
| 连接数 | 每个域名 6 个连接 | 单一长连接 | 减少 TCP 握手和 TLS 握手耗时,TCP 拥塞窗口预热更快。 |
| 并发方式 | 串行 (受限于队头阻塞) | 多路复用 | 彻底解决应用层队头阻塞,极大提高并发度。 |
| 数据格式 | 文本 (ASCII) | 二进制 (Binary) | 解析更高效,传输更紧凑。 |
| 头部传输 | 纯文本,大量重复 | HPACK 压缩 | 节省带宽,显著减少小请求的延迟。 |
补充说明:HTTP/2 的局限性
虽然 HTTP/2 解决了应用层(HTTP)的队头阻塞,但它依然基于 TCP 协议。如果 TCP 出现丢包,操作系统会暂停将数据传递给应用层,直到丢的包重传成功。这意味着 TCP 层面的队头阻塞 依然存在。这也是为什么后来出现了基于 UDP 的 HTTP/3 (QUIC) 的原因。