![管道化 HTTP 请求真的能加快页面加载速度吗?为什么?](https://linux22.com/image/1365308/%E7%AE%A1%E9%81%93%E5%8C%96%20HTTP%20%E8%AF%B7%E6%B1%82%E7%9C%9F%E7%9A%84%E8%83%BD%E5%8A%A0%E5%BF%AB%E9%A1%B5%E9%9D%A2%E5%8A%A0%E8%BD%BD%E9%80%9F%E5%BA%A6%E5%90%97%EF%BC%9F%E4%B8%BA%E4%BB%80%E4%B9%88%EF%BC%9F.png)
经常被引用的论点基本上就是这张图片中所包含的论点
然而,这并没有反映出底层 TCP 连接的真实情况,即必须缓慢启动,并且客户端会确认从服务器收到的每一个其他段。每当客户端有东西要发送(例如 HTTP 请求)时,ACK 就会被搭载。那么这里的好处在哪里呢?
答案1
流水线比纯持久 HTTP 连接更快的原因如下:
- 多个 HTTP 请求可以在单个 TCP 段中分批处理
- 多个 HTTP 回复(针对小文件)可以分批处理到单个(或更少)TCP 段中
- 慢启动其实很快,也就是指数级的。n往返时间,批次大小已经介于2^n到2^(n+1)段长。对于n=10,这意味着每 RTT 有 1024…2048 个段或(通常)140…300 千字节。
- 如果 TCP 连接仍然从先前的 HTTP 请求(或一组请求)保持打开状态,则我们已经脱离了慢启动阶段。
由于流水线对于大多数系统来说都很容易实现,所以无论如何我都会选择它。
答案2
这样做的好处是尽可能保持管道充满,而不是让它在请求之间耗尽。
通过流水线技术,管道的服务器->客户端方向始终保持满载,以实现最大吞吐量和最小延迟。
如果没有流水线,您就会得到一个“停止并等待”协议,其中服务器 -> 客户端方向在发送一个响应的最后一帧和发送下一个响应的第一帧之间保持空闲状态。管道在所有这些事情发生所需的整个累计时间内处于空闲状态:
- 第一个服务器响应的最后一帧在网络中传输所需的时间。
- 客户端收到该帧后采取行动并准备新请求所需的时间。
- 新的客户端请求传输网络所需的时间。
- 服务器准备对新请求的响应所需的时间。