外观
HTTP/1.0、1.1、2、3 差在哪?
HTTP/1.1 让连接可以复用,并有分块传输和强制的 Host。HTTP/2 在一条连接上多路复用二进制帧,还有头部压缩。HTTP/3 换成 QUIC,避免 TCP 上一条流丢包挡住所有流。
原理
HTTP/1.0 默认一个请求结束就关连接。浏览器要为每个文件重复握手。1.1 的 keep-alive 让多个请求排队走同一条连接,但同一个连接里仍然一个响应没完不能发下一个响应的内容,这是队头阻塞。于是浏览器对同一主机开多条连接。
HTTP/2 把报文拆成帧,多个流交错发送。头部用 HPACK 压缩。服务器还可以推送资源,实践里推送常常浪费带宽,现在更常用 preload 由页面声明。HTTP/2 仍受 TCP 丢包影响:一个包丢失,这条连接上的流都要等重传。
HTTP/3 的 QUIC 基于 UDP,每个流独立重传,握手也能和 TLS 合并,减少往返。部署依赖服务端和中间网络对 UDP 的支持。
文本状态行和头变成二进制帧之后,抓包要用支持 HTTP/2、HTTP/3 的工具看,不能按纯文本一行行读。
追问
上了 HTTP/2 还要雪碧图和域名分片吗?
多路复用之后,为了绕开连接数限制而拆很多域名,反而多了握手。合并雪碧图的必要性下降。仍要控制文件数量和缓存粒度:改一个图标不必让所有图标缓存失效。
服务端推送还要开吗?
多数情况不要。推送的资源用户缓存里可能已经有了。让 HTML 里的 preload 告诉浏览器优先级。
易错点
- 说 HTTP/2 解决了所有队头阻塞。它解决的是应用层「一个响应占住连接」,TCP 层的阻塞还在。
- 把 HTTP/3 理解成「更快的 HTTP/2」,传输已经换了。
- 在很多域名上各建一条 HTTP/2 连接,连接复用的好处被拆掉。