在《连接篇》中,我们聊到了物理层面的“极限”。而从 HTTP/1.1 到 HTTP/3 的演进史,本质上就是人类为了对抗物理延迟、提升带宽利用率而进行的一场持续十年的“带宽保卫战”。
作为前端开发者,理解这些演进不仅是面试的必考题,更是你配置 Nginx、调整构建策略(Webpack/Vite)的理论基石。
一、 HTTP/1.1:排队等待的时代
HTTP/1.1 是最长寿的协议,但它有一个致命的缺陷:线端阻塞(Head-of-Line Blocking) 。
-
串行请求: 在一个 TCP 连接上,请求是必须排队的。如果第一个请求(比如一个超大的 JS 文件)卡住了,后面的所有请求(图片、CSS)都得等着。
-
前端的“无奈之举”: * 域名分片(Domain Sharding): 浏览器对同一个域名的并发连接有限制(通常是 6 个)。于是我们搞出了
img1.cdn.com,img2.cdn.com来绕过限制。- 资源合并: 为了减少请求数,我们拼命搞雪碧图(Sprites)、合并 JS/CSS,甚至把图片转成 Base64 内联。
二、 HTTP/2:多路复用的革命
2015 年发布的 HTTP/2 彻底改变了游戏规则。它不再是基于文本的协议,而是**二进制分帧(Binary Framing)**协议。
1. 多路复用 (Multiplexing)
这是 HTTP/2 的杀手锏。它允许在同一个 TCP 连接上并行发出无数个请求。
- 不再排队: 每个请求被切成碎片(帧),混在一起发过去,接收端再按 ID 组装。
- 前端影响: 我们不再需要域名分片,甚至不再需要过度合并代码。微小的文件反而更有利于缓存利用。
2. 头部压缩 (HPACK)
HTTP 请求头(Cookie, User-Agent)往往很大且重复。HTTP/2 在客户端和服务器维护一张索引表,重复的头只发索引号。
- 效果: 极大地减少了带宽消耗,尤其是在移动端弱网下,首字节时间(TTFB)显著提升。
三、 HTTP/3:彻底摆脱 TCP 的枷锁
虽然 HTTP/2 解决了应用层的排队问题,但它依然逃不出 TCP 的队头阻塞(见连接篇)。只要丢一个包,整条连接就得重传。
HTTP/3 放弃了 TCP,转而基于 UDP 开发了 QUIC 协议:
- 真正的并行: 丢包只影响丢包的那一个流,其他流照样传输。
- 更快的连接: 合并了连接握手和加密握手,实现 0-RTT 或 1-RTT 启动。
- 连接迁移: 你从电梯出来,信号从 4G 换成了 WiFi,IP 变了,但你的视频播放不会卡顿,因为 HTTP/3 是基于 Connection ID 而不是 IP 地址的。
四、 前端视角:构建策略的“拨乱反正”
协议的演进直接影响了我们的工程化方案。作为 8 年经验的全栈,你需要根据协议调整你的构建策略:
| 构建策略 | HTTP/1.1 时代 | HTTP/2 / 3 时代 |
|---|---|---|
| JS/CSS 合并 | 必须合并成大包(减少请求数) | 不建议过度合并。拆分成小的模块更有利于增量缓存。 |
| 图片处理 | 雪碧图(Sprites) | 建议独立请求。 |
| 域名分片 | 需要多个 CDN 域名 | 禁止分片。分片会导致多次 DNS 解析和 TCP 握手,反而变慢。 |
| 静态资源加载 | 顺序加载 | 利用 Server Push 或 rel="preload" 预加载关键资源。 |
💡 前端硬核避坑贴士
- 服务器端推送(Server Push)要慎用: 虽然 HTTP/2 支持,但如果浏览器已经缓存了该资源,推送反而浪费带宽。现在工业界更倾向于使用
103 Early Hints。 - HTTP/2 并不是万灵药: 在丢包率超过 2% 的极差网络下,HTTP/2 由于 TCP 队头阻塞,表现可能还不如 HTTP/1.1。这也是为什么大厂都在推 HTTP/3。
结语
从 1.1 的串行,到 2.0 的并发,再到 3.0 的原生并行,协议的每一次跳跃都是为了抢回那几百毫秒的白屏时间。理解了这些,你就理解了现代性能优化的底层逻辑。