HTTP/2相较HTTP/1,大幅度提升了网页性能,使用HTTP/2协议,即可减少很多之前所做的性能优化工作。

HTTP/2虽然提升了 网页性能,但仍存在一些缺陷,HTTP/3是为了解决HTTP/2的问题而推出的

HTTP协议

HTTP,超文本传输协议,是互联网上运用最为广泛的协议。

所有的WWW文件都必须遵守这个标准。

是从WWW服务器传输超文本到本地浏览器的传输协议。

设计HTTP最初的目的是提供一种接收和发送HTML页面的方法。

HTTP客户端发起一个请求,建立一个到服务器指定端口(默认80端口)的TCP连接。

HTTP协议与TCP协议并不冲突,HTTP定义在七层协议中的应用层,TCP解决的是传输层的逻辑。

HTTP协议的瓶颈及其优化技巧都是基于TCP协议本身的特性。

  • 使用HTTP长链接的方案,优化TCP建立连接三次握手带来的延迟
  • 连接的重用来优化性能。TCP建立连接初期慢启动特性,所以连接重用比新建连接性能要好。

HTTP连接使用的是请求-响应的方式,在请求时需要先建立连接,客户端想服务端发起请求后,服务端才会回复数据。

客户端时依据域名向服务器建立连接的,一般PC端浏览器回针对单个域名的服务同时建立6~8个连接买手机端的连接一般控制在4~6个。

HTTP1.0

为了提高系统的效率,HTTP1.0规定浏览器与服务器只能保持短暂的连接。浏览器每次请求都需要与服务器建立一个TCP连接,服务器处理完成请求后回立即断开TCP连接。服务器不跟踪每个客户,也不记录过去的请求。

缺点

  1. 连接无法复用,当访问一个包含了很多图片请求的网页时,客户端需要与服务端建立连接,请求Html文件。在解析Html时,发现图片资源需要向服务器请求,故而整个页面需要向服务器发起多次连接,完成多次请求和响应。严重影响了客户端和服务器的性能。

  2. 队头阻塞,当顺序发送的请求序列中的一个请求因为某种原因被阻塞时,在后面排队的所有请求也一并被阻塞,会导致客户端迟迟收不到数据。队头阻塞导致带宽无法被充分利用,以及后续健康请求被阻塞。

HTTP1.1

为了解决HTTP1.0的缺点,

HTTP1.1支持持久连接,允许在一个TCP连接上传输多个HTTP请求和响应,减少建立连接和关闭连接的消耗和延迟。

HTTP1.1实行管道机制允许客户端不必等待上一次请求响应结束,即可发送下一次请求。服务端按照接收到的客户端请求先后顺序依次回应响应。即保证客户端能够区分每次请求的响应,有减少了整个页面下载所需要的时间。

HTTP1.1采用流模式传输文件,实现断点传输

HTTP1.1添加了新的请求方式:

  • PUT:请求服务器存储一个资源;
  • DELETE:请求服务器删除标识的资源;
  • OPTIONS:请求查询服务器的性能,或者查询与资源相关的选项和需求;
  • TRACE:请求服务器回送收到的请求信息,主要用于测试或诊断;
  • CONNECT:保留将来使用

HTTP 1.1通过增加更多的请求头和响应头来改进和扩充HTTP 1.0的功能。

  • 增加Host请求头字段,Web浏览器可以使用主机头名来明确表示要访问服务器上的那个Web站点,实现在一台Web服务器上可以在同一个IP地址和端口号上使用不同的主机名来创建多个虚拟站点。
  • Connection请求头值为Keep-Alive时,实现持续连接。值为close时,完成一次请求响应即断开连接。
  • Authorization请求头,用于验证用户身份
  • 状态管理,如Set-Cookie,Cookie,用于携带客户端与服务端之间的状态信息。
  • 添加Cache-Control头实现Cache缓存
    • Cache-Control:no-store:没有缓存
    • Cache-Control:no-cache:缓存,但重新验证
    • Cache-Control:private:私有缓存,响应只用于某单个用户,中间人不能缓存,响应只应用于浏览器私有缓存中
    • Cache-Control:public:公共缓存,响应可以被任何中间人缓存。
    • Cache-Control:max-age=3000:缓存过期时间,毫秒计算
    • Cache-Control:must-revalidate:验证方式,缓存在考虑使用一个陈旧的资源时,必须先验证它的状态,已过期的缓存将不被使用。

但是,HTTP1.1仍有一些缺点

  1. 高延迟–页面加载速度降低

    虽然允许复用TCP连接,但是同一个TCP连接里面,所有的数据通信是按次序进行的。服务器只有处理完一个请求,才会接着处理下一个请求。仍会出现队头阻塞问题。

    解决方案

    • 将同一页面的资源分散到不同域名下,提升连接上限

    • 雪碧图,合并多张小图为一张大图

    • 图片的原始数据嵌入在 CSS 文件里面的 URL 里,减少网络请求次数

      1
      2
      3
      .icon {
      background: url(data:image/png;base64,<data>) no-repeat;
      }
    • 将多个小的js文件合并打包为一个较大的文件

  2. 无状态特性—HTTP头部巨大

    Header一般会携带一些固定字段,Header 里携带的内容过大,在一定程度上增加了传输成本。

  3. 明文传输–不安全

    HTTP1.1 在传输数据时,所有传输的内容都是明文传输,客户端和服务器端都无法验证对方的身份,在一定程度上无法保证数据的安全性。

  4. 不支持服务器推送消息

    响应信息必须由客户端发起请求,服务端才会给予回复响应。

HTTP1.0和HTTP1.1的一些区别

  1. 缓存处理

    HTTP1.0在Header中使用If-Modified-Since,Expires来作为缓存判断的标准

    HTTP1.1引入了更多缓存控制策略Entity tagIf-Unmodified-SinceIf-Match,、If-None-Match

  2. 文件传输模式

    HTTP1.0文件采用“数据块”传输,无法获取资源的部分内容,也无法实现断点续传

    HTTP1.1文件采用“流模式”传输,可以请求资源的部分内容(使用range头控制),也可以显示断点传输

    1
    <code>RANGE:bytes=XXXX</code>
  3. 长连接

    HTTP1.1通过Connection头实现客户端与服务端的长连接

  4. Host头处理

    HTTP1.1通过Host头名,实现一台Web服务器上建立多个虚拟Web站点

  5. 新增多种请求方式

  6. 新增多种状态码

HTTP2.0

HTTP2.0专注于性能,最大的目标是在用户和网站间只用一个连接。使用 HTTP/2 能带来 20%~60% 的效率提升。

HTTP2新特性

1. 二进制传输

HTTP2 采用二进制格式传输数据,而非HTTP1.x中采用的纯文本形式。二进制协议解析起来更高效。

HTTP2讲请求和响应数据分割为更小的帧,并且采用二进制编码。

将原来的“Header+Body”消息打散为多个小片的二进制帧,用HEADERS帧存放头数据,用Data帧存放实体数据。

在 HTTP/2 中:

  • 同域名下所有通信在同一个连接上完成
  • 单个连接可以承载任意数量的双向数据流
  • 数据以消息的形式发送,消息由帧组成,多个帧之间可以乱序发送,根据帧首部的流标识可以重新组装。

2. 多路复用

多路复用很好的解决了浏览器限制同一个域名下请求数量的问题,同时也更容易实现全速传输。

HTTP2二进制分帧之后,不再依赖 TCP 链接去实现多流并行了,在 HTTP/2 中:

  • 同域名下所有通信在同一个连接上完成
  • 单个连接可以承载任意数量的双向数据流
  • 数据以消息的形式发送,消息由帧组成,多个帧之间可以乱序发送,根据帧首部的流标识可以重新组装。

正式因为二进制传输与多路复用,使得性能有了极大的提升:

  • 同域名只需要占用一个TCP连接,下载多个资源时,避免了多次三次握手连接及慢启动延迟,同时也避免了多个TCP连接竞争带宽所带来的问题。
  • 并行交错的发送请求/响应,请求/响应间互不干扰。
  • HTTP2中,每个请求都可以带有一个31bit的优先值,0 表示最高优先级, 数值越大优先级越低。利用优先值,客户端可服务端可以在处理不同的流时采取不同的策略,以最优的方式发送流、消息和帧。

3. Header压缩

HTTP2专门开发了””HPACK“压缩,在客户端与服务端之间建立字典,用索引号表示重复的字符串,采用哈夫曼编码来压缩整数和字符串,显示50%~90%的压缩率。

  • 在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键 - 值对,对于相同的数据,不再通过每次请求和响应发送。
  • 首部表在 HTTP/2 的连接存续期内始终存在,由客户端和服务器共同渐进地更新 。
  • 每个新的首部键 - 值对要么被追加到当前表的末尾,要么替换表中之前的值

4. 服务端推送

服务端可以新建“流”,主动向客户端发送消息。

服务端可以主动推送,客户端也有权利选择是否接收。如果服务端推送的资源已经被浏览器缓存过,浏览器可以通过发送 RST_STREAM 帧来拒收。

主动推送也遵守同源策略。

5.提高安全性

HTTP2不强制使用加密通信,但是由于各大主流浏览器宣布只支持加密的HTTP2,所以,实际上,HTTP2传输是加密的。

HTTP2缺点

HTTP2的缺点主要是由TCP协议造成的

  1. TCP 和 TCP+TLS 建立连接的延时

    HTTP2是通过TCP协议来传输的,如果使用HTTPS的话,还需要使用TLS协议进行安全传输。

    整个过程,则需要两次两个握手过程,TCP三次握手需要消耗1.5个RTT(round-trip time),TLS连接大致需要1~2个RTT,即在数据传输前,即已消耗3~4个RTT。

  2. TCP头部阻塞问题没有彻底解决

    当传输过程发生丢包时,TCP“丢包重传”机制,丢失的包必须要等待重新传输确认,整个TCP都要等待重传,会阻塞TCP连接中的所有请求

HTTP3

一个基于 UDP 协议的“QUIC”协议,让 HTTP 跑在 QUIC 上而不是 TCP 上,是HTTP/3 中的底层支撑协议。

HTTP3 的主要改进在传输层上。传输层不会再有我前面提到的那些繁重的 TCP 连接了。现在,一切都会走 UDP。

UDP 是“无连接”的,根本就不需要“握手”和“挥手”,但是QUIC 也实现了可靠传输,保证数据一定能够抵达目的地。

QUIC新特性

1. 实现了类似 TCP 的流量控制、传输可靠性的功能。

虽然UDP不提供可靠性的传输,但是基于UDP的QUIC在UDP的基础上增加了一层来保证数据传输的可靠性。

提供了数据包重传、拥塞控制以及其他一些TCP中存在的特性。

2.实现了快速握手功能

QUIC是基于UDP的,所以QUIC可以实现使用0-RTT或1-RTT来建立连接,这意味着QUIC可以使用最快的速度来进行数据传输。

3. 集成了TLS加密功能

目前 QUIC 使用的是 TLS1.3,相较于早期版本 TLS1.3 有更多的优点,其中最重要的一点是减少了握手所花费的 RTT 个数。

4. 多路复用,彻底解决 TCP 中队头阻塞的问题

QUIC 实现了在同一物理连接上可以有多个独立的逻辑数据流。实现了数据流的单独传输,就解决了 TCP 中队头阻塞的问题

总结

HTTP1.0

特点

每次请求都要新建立TCP连接,请求/响应结束后即终止连接,服务端不做记录和追踪。

缺点

  1. TCP连接无法复用,连接耗时,有延迟。
  2. 队头阻塞
  3. 明文传输,不安全

HTTP1.1

特点

  1. TCP连接支持长连接
  2. 管道传输,文件传输采用“文件流”的形式,可以进行资源部分加载及断点续传
  3. 丰富了Header头部,支持更多的缓存控制
  4. 头部添加Host,允许服务器对同一IP,同一端口建立多个虚拟Web站点
  5. 新增状态码
  6. 新增多种请求方式

缺点

  1. 明文传输,不安全
  2. Header头部巨大,多次请求,重复信息需要重复传输,消耗性能
  3. 队头阻塞问题
  4. 不支持服务器推送

HTTP2

特点

  1. 二进制传输
  2. 多路复用
  3. 未规定加密传输,但实际主流浏览器仅支持加密传输的HTTP2协议
  4. Header头部压缩
  5. 支持服务端推送

缺点

HTTP2的缺点主要是由TCP协议带来的

  1. 未彻底解决队头阻塞问题,当发生丢包时,TCP“丢包重传”机制,丢失的包必须要等待重新传输确认,整个TCP都要等待重传,会阻塞TCP连接中的所有请求。
  2. 当HTTP2使用HTTPS时,除了TCP协议,还需要使用TLS协议,需要两次握手过程

HTTP3

舍弃TCP连接,基于UDP协议的QUIC协议,让 HTTP 跑在 QUIC 上而不是 TCP 上。

特点

  1. 使用QUIC协议,而非TCP协议进行传输,但是具有TCP的可靠性连接。
  2. 实现了快速握手。
  3. 集成了TLS安全传输协议
  4. 多路复用,彻底解决了队头阻塞问题,在同一个物理连接上可以实现多路数据流传输。

参考

  1. https://www.infoq.cn/article/ku4okqr8vh123a8dlccj
  2. https://www.jianshu.com/p/52d86558ca57
  3. https://www.debugger.wiki/article/html/1565502376358922