HTTP/2 相比于 HTTP/1,能够说是大幅度提升了网页的性能,只须要升级到该协议就能够减小不少以前须要作的性能优化工做,固然兼容问题以及如何优雅降级应该是国内还不广泛使用的缘由之一。html
虽然 HTTP/2 提升了网页的性能,可是并不表明它已是完美的了,HTTP/3 就是为了解决 HTTP/2 所存在的一些问题而被推出来的。前端
想阅读更多优质文章请猛戳GitHub博客git
HTTP协议是HyperText Transfer Protocol(超文本传输协议)的缩写,它是互联网上应用最为普遍的一种网络协议。全部的WWW文件都必须遵照这个标准。伴随着计算机网络和浏览器的诞生,HTTP1.0也随之而来,处于计算机网络中的应用层,HTTP是创建在TCP协议之上,因此HTTP协议的瓶颈及其优化技巧都是基于TCP协议自己的特性,例如tcp创建链接的3次握手和断开链接的4次挥手以及每次创建链接带来的RTT延迟时间。github
链接没法复用:链接没法复用会致使每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显,慢启动则对大量小文件请求影响较大(没有达到最大窗口请求就被终止)。面试
Head-Of-Line Blocking(HOLB):致使带宽没法被充分利用,以及后续健康请求被阻塞。HOLB是指一系列包(package)由于第一个包被阻塞;当页面中须要请求不少资源的时候,HOLB(队头阻塞)会致使在达到最大请求数量时,剩余的资源须要等待其余资源请求完成后才能发起请求。浏览器
request-response
对按序发生。显然,若是某个请求长时间没有返回,那么接下来的请求就所有阻塞了。由于HTTP/1.x的问题,咱们会引入雪碧图、将小图内联、使用多个域名等等的方式来提升性能。不过这些优化都绕开了协议,直到2009年,谷歌公开了自行研发的 SPDY 协议,主要解决HTTP/1.1效率不高的问题。谷歌推出SPDY,才算是正式改造HTTP协议自己。下降延迟,压缩header等等,SPDY的实践证实了这些优化的效果,也最终带来HTTP/2的诞生。缓存
SPDY 协议在Chrome浏览器上证实可行之后,就被看成 HTTP/2 的基础,主要特性都在 HTTP/2 之中获得继承。安全
2015年,HTTP/2 发布。HTTP/2是现行HTTP协议(HTTP/1.x)的替代,但它不是重写,HTTP方法/状态码/语义都与HTTP/1.x同样。HTTP/2基于SPDY3,专一于性能,最大的一个目标是在用户和网站间只用一个链接(connection)。性能优化
HTTP/2由两个规范(Specification)组成:服务器
HTTP/2 采用二进制格式传输数据,而非 HTTP 1.x 的文本格式,二进制协议解析起来更高效。 HTTP / 1 的请求和响应报文,都是由起始行,首部和实体正文(可选)组成,各部分之间以文本换行符分隔。HTTP/2 将请求和响应数据分割为更小的帧,而且它们采用二进制编码。
接下来咱们介绍几个重要的概念:
HTTP/2 中,同域名下全部通讯都在单个链接上完成,该链接能够承载任意数量的双向数据流。每一个数据流都以消息的形式发送,而消息又由一个或多个帧组成。多个帧之间能够乱序发送,根据帧首部的流标识能够从新组装。
在 HTTP/2 中引入了多路复用的技术。多路复用很好的解决了浏览器限制同一个域名下的请求数量的问题,同时也接更容易实现全速传输,毕竟新开一个 TCP 链接都须要慢慢提高传输速度。
你们能够经过 该连接 直观感觉下 HTTP/2 比 HTTP/1 到底快了多少。
这一特性,使性能有了极大提高:
在 HTTP/1 中,咱们使用文本的形式传输 header,在 header 携带 cookie 的状况下,可能每次都须要重复传输几百到几千的字节。
为了减小这块的资源消耗并提高性能, HTTP/2对这些首部采起了压缩策略:
例以下图中的两个请求, 请求一发送了全部的头部字段,第二个请求则只须要发送差别数据,这样能够减小冗余数据,下降开销
Server Push即服务端能经过push的方式将客户端须要的内容预先推送过去,也叫“cache push”。
能够想象如下状况,某些资源客户端是必定会请求的,这时就能够采起服务端 push 的技术,提早给客户端推送必要的资源,这样就能够相对减小一点延迟时间。固然在浏览器兼容的状况下你也可使用 prefetch。 例如服务端能够主动把JS和CSS文件推送给客户端,而不须要客户端解析HTML时再发送这些请求。
服务端能够主动推送,客户端也有权利选择是否接收。若是服务端推送的资源已经被浏览器缓存过,浏览器能够经过发送RST_STREAM帧来拒收。主动推送也遵照同源策略,换句话说,服务器不能随便将第三方资源推送给客户端,而必须是通过双方确认才行。
虽然 HTTP/2 解决了不少以前旧版本的问题,可是它仍是存在一个巨大的问题,主要是底层支撑的 TCP 协议形成的。
上文提到 HTTP/2 使用了多路复用,通常来讲同一域名下只须要使用一个 TCP 链接。但当这个链接中出现了丢包的状况,那就会致使 HTTP/2 的表现状况反倒不如 HTTP/1 了。
由于在出现丢包的状况下,整个 TCP 都要开始等待重传,也就致使了后面的全部数据都被阻塞了。可是对于 HTTP/1.1 来讲,能够开启多个 TCP 链接,出现这种状况反到只会影响其中一个链接,剩余的 TCP 链接还能够正常传输数据。
那么可能就会有人考虑到去修改 TCP 协议,其实这已是一件不可能完成的任务了。由于 TCP 存在的时间实在太长,已经充斥在各类设备中,而且这个协议是由操做系统实现的,更新起来不大现实。
基于这个缘由,Google 就更起炉灶搞了一个基于 UDP 协议的 QUIC 协议,而且使用在了 HTTP/3 上,HTTP/3 以前名为 HTTP-over-QUIC,从这个名字中咱们也能够发现,HTTP/3 最大的改造就是使用了 QUIC。 QUIC 虽然基于 UDP,可是在本来的基础上新增了不少功能,接下来咱们重点介绍几个QUIC新功能。
经过使用相似 TCP 快速打开的技术,缓存当前会话的上下文,在下次恢复会话的时候,只须要将以前的缓存传递给服务端验证经过就能够进行传输了。0RTT 建连能够说是 QUIC 相比 HTTP2 最大的性能优点。那什么是 0RTT 建连呢?
这里面有两层含义:
1.传输层 0RTT 就能创建链接。
2.加密层 0RTT 就能创建加密链接。
上图左边是 HTTPS 的一次彻底握手的建连过程,须要 3 个 RTT。就算是会话复用也须要至少 2 个 RTT。
而 QUIC 呢?因为创建在 UDP 的基础上,同时又实现了 0RTT 的安全握手,因此在大部分状况下,只须要 0 个 RTT 就能实现数据发送,在实现前向加密的基础上,而且 0RTT 的成功率相比 TLS 的会话记录单要高不少。
虽然 HTTP/2 支持了多路复用,可是 TCP 协议终究是没有这个功能的。QUIC 原生就实现了这个功能,而且传输的单个数据流能够保证有序交付且不会影响其余的数据流,这样的技术就解决了以前 TCP 存在的问题。
同HTTP2.0同样,同一条 QUIC链接上能够建立多个stream,来发送多个HTTP请求,可是,QUIC是基于UDP的,一个链接上的多个stream之间没有依赖。好比下图中stream2丢了一个UDP包,不会影响后面跟着 Stream3 和 Stream4,不存在 TCP 队头阻塞。虽然stream2的那个包须要从新传,可是stream三、stream4的包无需等待,就能够发给用户。
TCP 协议头部没有通过任何加密和认证,因此在传输过程当中很容易被中间网络设备篡改,注入和窃听。好比修改序列号、滑动窗口。这些行为有多是出于性能优化,也有多是主动攻击。
可是 QUIC 的 packet 能够说是武装到了牙齿。除了个别报文好比 PUBLIC_RESET 和 CHLO,全部报文头部都是通过认证的,报文 Body 都是通过加密的。
这样只要对 QUIC 报文任何修改,接收端都可以及时发现,有效地下降了安全风险。
如上图所示,红色部分是 Stream Frame 的报文头部,有认证。绿色部分是报文内容,所有通过加密。
QUIC协议有一个很是独特的特性,称为向前纠错 (Forward Error Correction,FEC),每一个数据包除了它自己的内容以外,还包括了部分其余数据包的数据,所以少许的丢包能够经过其余包的冗余数据直接组装而无需重传。向前纠错牺牲了每一个数据包能够发送数据的上限,可是减小了由于丢包致使的数据重传,由于数据重传将会消耗更多的时间(包括确认数据包丢失、请求重传、等待新数据包等步骤的时间消耗)
假如说此次我要发送三个包,那么协议会算出这三个包的异或值并单独发出一个校验包,也就是总共发出了四个包。当出现其中的非校验包丢包的状况时,能够经过另外三个包计算出丢失的数据包的内容。固然这种技术只能使用在丢失一个包的状况下,若是出现丢失多个包就不能使用纠错机制了,只能使用重传的方式了。
给你们推荐一个好用的BUG监控工具Fundebug,欢迎免费试用!
欢迎关注公众号:前端工匠,你的成长咱们一块儿见证!若是你感受有收获,欢迎给我打赏,以激励我更多输出优质开源内容