前言
即使我们拥有百兆带宽,在使用 HTTP/1.1 时也常感到网页加载有“延迟感”。这种带宽利用率低下的根源不在于网速,而在于协议本身的机制。HTTP/2.0 的出现,通过底层架构的重构,彻底解决了这些顽疾。
一、 回顾:HTTP/1.1 为什么快不起来?
HTTP/1.1 对带宽的利用率极低,通常只能利用到物理带宽的 20% 左右,主要受限于以下三个因素:
1. TCP 的慢启动 (Slow Start)
TCP 连接建立后,为了防止网络拥塞,会先以极慢的速度发送数据,再逐步增加。
- 痛点:网页加载最关键的是 HTML、CSS 等小文件,往往还没等到 TCP 提到“高速”,文件就传完了,这极大地推迟了首次渲染时间。
2. 多条 TCP 连接的带宽竞争
由于单个连接有队头阻塞,浏览器通常会针对同一域名开启 6 个 TCP 连接。
- 痛点:这些连接是“竞争关系”。如果下载图片的连接抢占了带宽,下载关键资源(JS/CSS)的连接就会变慢,且无法通过协议层面进行优先级协商。
3. HTTP 层的队头阻塞 (HOL Blocking)
- 痛点:在同一个 TCP 通道中,必须等前一个请求的响应返回,才能发送下一个。如果其中一个请求卡住,后续所有请求都会被阻塞。
二、 核心革命:二进制分帧层 (Binary Framing)
HTTP/2.0 并没有改变 HTTP 的语义(方法、状态码等依然存在),而是在应用层与传输层之间增加了一个 二进制分帧层。
实现原理:
- 分帧处理:浏览器将请求(行、头、体)交给二进制分帧层,数据被切分为一个个带 Stream ID 编号的“帧”。
- 乱序传输:这些帧可以在同一个 TCP 连接上乱序发送,不再需要排队。
- 服务端组装:服务器接收到帧后,根据 ID 编号将它们重新组合成完整的请求。
- 双向流动:响应数据同样被切帧发送,浏览器按 ID 还原。
三、 HTTP/2.0 的四大王牌特性
1. 多路复用 (Multiplexing) —— 核心中的核心
- 能力:在一个 TCP 连接上可以同时发起无数个请求和响应。
- 优势:消除了 HTTP 层的队头阻塞。当服务器遇到优先级高的请求(如 CSS),可以暂停当前图片帧的发送,优先传输关键资源帧。
2. 设置请求优先级 (Stream Priority)
- 能力:客户端可以在帧中标记权重。
- 优势:服务器接收到请求后,会优先分配 CPU 和带宽资源处理重要信息,确保核心体验先到达。
3. 服务器推送 (Server Push)
- 能力:服务器可以“预测”需求。
- 优势:用户请求
index.html时,服务器知道它必然需要style.css,于是主动将其推送到客户端缓存。当浏览器解析 HTML 发现需要 CSS 时,它已经在本地了,实现了“零时延”加载。
4. 头部压缩 (HPACK)
- 背景:HTTP/1.1 的 Header 往往包含大量重复信息(如 Cookie、User-Agent),浪费流量。
- 方案:HTTP/2.0 在客户端和服务器共同维护一张静态/动态表,并对 Header 进行 Huffman 编码。
- 优势:相同的头信息不再重复传输,只发送索引号,大幅提升了传输效率。
四、 总结
HTTP/2.0 通过二进制分帧实现了多路复用,配合头部压缩和服务器推送,极大地压榨了带宽性能,目前大多数HTTP都是采用Http2.0,例如掘金的请求中。
⚠️ 最后的思考: 虽然 HTTP/2 解决了 HTTP 层的队头阻塞,但如果底层 TCP 发生丢包,整个 TCP 连接依然会阻塞。为了解决这个“TCP 层的队头阻塞”,我们才迎来了基于 UDP 的 HTTP/3 (QUIC) 。