为了让我们的网站访问速度快变,我们不断增加带宽,做针对HTTP协议的特点对应用做各种优化。希望能通常高带宽,低延迟来提高网站到访问速度。带宽与延迟两者间,延迟才是性能的真正瓶颈。

客观原因

当我们针对HTTP协议进行性能优化时,我们不得不注意到这样的一些客观原因。通常当我们改变不了底层协议特性时,我们只能在更高层处做文章。

  1. 带宽受物理层介质的影响,最快快不过光速,但是即便在今天越来越高的带宽,我们依然没有感觉到网站访问速度有多快。

  2. 延迟包括传输延迟,传播延迟,处理延迟和排队延迟。

  3. 每次连接都需要经过3次握手才能建立,增加整整一个RTT。

  4. TCP拥塞控制策略:慢启动,拥塞避免[注1]。其中慢启动会被应用到每一个连接中。TCP流量和拥塞控制会影响整个网络到吞吐量。

  5. 解析DNS必然会产生一些延迟。

  6. 最快获得资源的方式,莫过于还没传,就已拿到。充分利用缓存。

  7. 最少的延迟就是什么都不传。而没有延迟。

针对HTTP1.X做过的优化

由于TCP层的特性,在提高web性能时,我们不得不做一些优化,
Best Practices for Speeding Up Your Web Site,这些优化中针对HTTP协议特点的,我们做了哪些呢,从总体来说有以下几大点。

  • 连接和拼接

    连接或拼接JS和CSS文件,雪碧图,以减少HTTP请求,同时浏览器可缓存这些静态资源,为下次访问节约时间。但是这样带来的副作用是,维护成本高,其中某一个小改动都会使得整个拼接后的文件发生改变,重新缓存。

  • 域名分区

    由于浏览器的限制,同一个域下最多只能建立6个连接。我们通常使用子域名来减少所有资源在只有一个连接时的产生的排队延迟。这个显然不适用在HTTP2中,因为不同的域需要建立不同的连接。

  • 资源内嵌

    对于不常用的,较小大资源内嵌在文档中,比如base64的图片,以减少HTTP请求,但是这样的资源不能在浏览器中缓存,也不可能被其他页面共享,同时还有可能编码之后的资源变等更大了。在HTTP2中,这样的资源就可以使用SERVER PUSH来推送。

  • HTTP管道(额外的)

    在HTTP1.x中已经实现了持久连接,但是却依然需要排队来发送和接收请求,这样不能充分利用网络资源。因此提出了HTTP管道的概念。客户端可以将所有请求都一起发给服务器端,服务器端或者按顺序处理,或者并行处理这些请求。但是返回响应的顺序是按照其自己内部的优先级来的。

    但是,其缺点也很多,以至于现在的浏览器对它还是默认关闭的:

    1. 队首阻塞
    2. 并行处理时,需要占用缓存资源,服务器容易受到攻击
    3. 响应失败后,会断开tcp连接,并要求重发之后的所有请求,造成资源浪费
    4. 中间代理对其兼容性不是很好,有可能还会串行所有请求

针对HTTP2需要做的优化

  • 坚决去掉在HTTP1.X中的域名分区,连接和拼接和资源内嵌的优化方式。
  • 尽量让所有资源在同一域名下
  • 利用服务器推送
  • 继续保留CDN

一切都已返璞归真

  • TCP慢开始与拥塞避免示意图

参考

  1. HTTP2.0的奇妙日常
  2. HTTP请求的TCP瓶颈分析
  3. Http 2.0协议简介