HTTP2 基础知识点总结

最近读完《HTTP2 基础教程》,至关因而对 HTTP2 有了个大体的了解,本文已加入个人博客,感谢你们支持!css

HTTP 发展史

互联网刚开始的时候,人们浏览网页只是为了阅读文字,随着时代的不断发展,人们对于网站的需求愈来愈高,一个网站不只仅要展现文字,还要展现图片,视频,3D 特效等。html

一、Web 页面引用的内容每一年都在增加,图片,JS,CSS 愈来愈大,也愈来愈多。git

二、Web 所依赖的资源也变得愈来愈复杂。github

三、大多数 Web 页面会关联数十个域名的资源,每个资源都须要经历一次 DNS,TCP,TLS 等。算法

HTTP1.1 阶段

人们对网站的需求愈来愈多,可是 HTTP 协议却发展很慢,HTTP1.1 已经存在 20 年了,却仍是当前社会中使用最普遍的协议。如下几个缺点也愈来愈被你们所关注:浏览器

一、队头阻塞,在请求响应中若是出现任何问题,剩下的工做都会被阻塞在那次请求应答以后。缓存

二、低效的 TCP 利用安全

拥塞窗口:在接收方确认数据包以前,发送方能够发出的 TCP 包的数量。(例如:若是拥塞窗口为 1,那么发送方发出 1 个数据包以后,只有接收方确认了那个包,才能发送下一个)。服务器

TCP 中有个概念叫慢启动,目的是为了让新链接搞清楚当前的网络情况,避免给已经拥堵的网络继续添乱。(它容许客户端在收到每一个确认回复后额外发送 1 个未确认包,这意味着新链接在收到 1 个确认回复后,能够发送 2 个数据包,在收到 2 个确认回复后,能够发 4 个,以此类推,直到达到上限值)cookie

三、臃肿的消息首部

虽然 HTTP1 提供了压缩请求内容的机制,可是消息首部却没法压缩,若是算上 cookie,可能每次都会多发送几千个字节。

四、受限制的优先级设置

HTTP1 没有优先级一说,要么发起请求,要么不发起。

Web 性能调优

为了解决 HTTP1 的各类问题,你们也总结一下优化方案,咱们来依次介绍一下吧。

网站运行流程(简化版)

  1. 输入 URL 并敲回车。
  2. 根据域名解析 IP 地址。
  3. 创建 TCP 链接管道。
  4. 若是是 HTTPS,进行 TLS 握手。
  5. 服务器端收到请求。
  6. 输出主体 HTML 。
  7. 客户端根据 HTML 内的其余资源进行请求。

若是想在 HTTP 协议层面作优化,能够考虑下几点:

  • DNS 查询时间
  • TCP 三次握手时间
  • TLS 安全协议时间(秘钥协商,对称加密,非对称加密)

DNS 查询优化

  • 限制不一样域名数量
  • 使用 dns-prefetch,在解析主体 HTML 的同时,就会解析制定域名。
<link rel="dns-prefetch" href="//www.xxx.com" />
  • 找一家好的外部供应商

优化 TCP 链接

  • 使用 preconnect 指令,让链接在使用以前就已经创建好。
<link rel="preconnect" href="//www.xxx.com" />
  • 尽早终止响应(借助 CDN,让传输更近)。

避免重定向

  • 利用 CDN 云端重定向。
  • 统一域名使用 Web 服务器上的 rewrite 规则,避免重定向。

缓存策略

咱们经常使用缓存来避免没必要要的请求,但要使用缓存必须遵照着两个概念:多用户之间可共享可以接受必定程度的旧数据

  • 纯静态不变的内容,能够永久缓存。
  • CSS/JS 等个性化资源,缓存时间是会话(交付)平均时间的两倍。
强缓存

使用 Expires 首部,将资源失效的日期告诉客户端,在失效如期以前,客户端都会直接使用缓存中的资源而不会发起请求

使用 Cache-Control 首部,进行更多的定制化缓存:

  • max-age 表示资源会缓存的具体时间
  • no-cache 不使用本地缓存。须要使用缓存协商。
  • no-store 直接禁止游览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源。
  • public 能够被全部的用户缓存,包括终端用户和 CDN 等中间代理服务器。
  • private 只能被终端用户的浏览器缓存,不容许 CDN 等中继缓存服务器对其缓存。
协商缓存

在请求中包含 HTTP 首部 Last Modified,仅当最新内容在首部中制定的日志以后被更新过,服务器才返回完整内容,不然返回 304.

在请求实体中包含实体校验码 ETag,它惟一标识所请求的资源,服务器会比较当前 ETag 与请求首部中收到 ETag,若是一致,就返回 304.

压缩和代码简化

删除 html 文档中的注释,换行,空格等,减小资源大小。

避免阻塞 CSS/JS

因为 JS 在处理时,会阻止其余任何资源的下载和渲染,可能会带来没必要要的延迟。

  • CSS 影响页面可视化效果,建议先请求。
  • JS 则须要正确用好 defer, async。

图片优化

一张图片中每每并非只有图片内容,每每还包含有一些图片元信息:地理位置信息,时间戳,尺寸,像素等。而这些信息对于页面并无声明用,还会增长图片的大小,建议删除掉图片元信息,只保留真正有用的部分。

另外,页面中的图片,尽可能不要使用 CSS 去拉伸或者缩放,须要多大的图片,就返回多大的图,避免资源浪费。

回归正题 HTTP2 核心概念

上面介绍了 HTTP 的历史以及现阶段使用最普遍的 HTTP1 ,接下来咱们来介绍一下 HTTP2 ,看一看 HTTP2 是怎么解决 HTTP1 所遗留的问题?

首先,要搭建 HTTP2 服务,必须配套使用 HTTPS 安全策略,才能获得浏览器的支持。HTTP2 其实并无要求必须使用 HTTPS,只是人们正好认识到 HTTPS 的重要性,而 HTTP2 正好出来,就不谋而合的结合在一块儿了

HTTP2 分层

  • 分帧层,即 HTTP2 多路复用能力的核心部分。
  • 数据或 HTTP 层,其中包含传统上被认为是 HTTP 及其相关数据的部分。

分帧会来来以下好处:

一、二进制协议:HTTP2 的分帧层是基于帧的二进制协议,方便机器解析。

二、首部压缩:仅仅使用二进制协议还不够,HTTP2 的首部还会被深度压缩。

三、多路复用:当你在使用 HTTP2 传输连接的时候,没必要等待上一个请求结束后才进行下一个请求,请求和响应能够交织在一块儿。

HTTP2 是基于帧的协议,为了将重要的信息都封装起来,让协议的解析方能够轻松的阅读、解析并还原信息。相比之下,HTTP1 并非基于帧的,而是以文原本分隔,服务器只能根据文本换行符来拆分请求数据。

使用 HTTP1 可能会产生如下问题:

  • 换行符对于每一个平台可能有兼容性问题,例若有些平台采用<crlf>,有些平台采用<lf>
  • 一次只能处理一个请求或响应,完成以前不能中止解析。
  • 没法预判解析须要多少内存,若是一行的信息量太大,超出了内存,会返回 400 错误

帧有着严格的结构格式,有了帧,处理协议的程序就能预先知道会受到什么,从而采起对应的解析方法。能够把帧理解为一个对象:

var frame = {
    length:'帧负载的长度',
    Type:'类型',
    Flags:'帧的标识',
    R:'保留位',
    Stream Identifer :'每一个流惟一ID',
    Frame Payload:'真实的帧内容'
}

这样以来,实现和维护都会简单不少,不用等到一个请求完成之后才进行下一次请求,请求和响应能够交错甚至可多路复用。

流是 HTTP2 连接上独立的,双向的帧序列交换。能够将流看做在链接上的一些列帧,他们构成了单独的 HTTP 请求和响应。

一、消息:泛指 HTTP 中一个请求或一个响应。

二、流量控制:当一段接收并消费被发送的数据时,它将发出一个 WINDOW_UPDATE 帧,用来表示其更新后的处理字节的能力。

确保一个流不会影响到其余的流。

三、优先级

首先请求网页上最重要的元素,以最优的顺序获取资源,由此来优化页面性能。

  • 经过 HEADERS 帧能够指明某些对象和其余对象的依赖关系。
  • 经过 PRIORITY 帧,能够告诉服务器如何肯定具备共同依赖关系的对象的优先级。

服务器推送

提高单个资源性能的最佳方式,就是在它被用到以前就放到了浏览器的缓存里,服务器端能够主动将资源发给客户端,这多是由于它知道客户端不久后将会用到该资源。

若是服务器决定推送一个对象,会经过 PUSH_PROMISE 帧去传递将会被推送的资源。

首部压缩

以前说到,HTTP1 中没有对首部进行压缩,这会在每次请求中发送大量的冗余首部,而 HTTP2 则解决了这个问题。HTTP2 没有使用 gzip 压缩,而是使用 HPACK,由于 GZIP 压缩有泄漏加密信息的风险,简称 CRIME。

CRIME 原理:攻击者在请求中添加数据,观察压缩加密后的数据量,若是变小了,就证实注入的数据和请求中的其余内容有重复,进而搞清楚全部的加密数据内容。

HTTP2 的 HPACK 原理:

当客户端请求时,会根据发送的首部信息,创建一张表:

索引 首部名称
62 header1 foo
63 header2 bar
64 header3 baz

服务器端再接收到数据的时候也会建立一张与之对应的表。客户端在发送下一个请求的时候,若是首部是相同的,就不用发送 Header 头,只用发送索引号就好了,服务器端会索引去还原对应的首部信息。

并不是必定能从 HTTP2 中获益

以前说了这么多 HTTP2 的好处,你是否已经以为升级 HTTP2 已经火烧眉毛了呢?可是 HTTP2 页不是完美的,这一小节咱们来介绍一下 HTTP2 的一些坑。

一、关于丢包。以前说到,HTTP2 采用多路复用,可让多个请求在同一个 TCP 链接中进行传输,可是因为 HTTP2 是单连接架构,若是惟一的链接发生了丢包,全部的工做都会受到影响,这实际上是 HTTP2 中比较大的坑。

HTTP1 在请求时创建了多个链接(和浏览器相关,通常为 6 个),相对于 TCP 的初始拥塞窗口更大。当有一个链接发生丢包时,不会影响到其余请求。对比之下: HTTP2 比 HTTP1 更容易丢包。

二、关于服务器端推送。以前说到,服务器端推送能够主动给客户端推送资源,用来减小客户端发起请求数量。但是这也可能带来一个问题:若是推送的资源在客户端已经缓存过,那就是画蛇添足了,因此在作服务器端渲染时,必定要和客户端的缓存策略结合起来。

HTTP2 反模式

HTTP2 部署以后,以前针对于 HTTP1 的优化方案有可能就不适用了,咱们来看一下都有哪些。

  • 域名拆分

在 HTTP1 中,会将一些静态资源存在多个 cdn 服务器(由于浏览器对同一个域名下的资源请求并发数有限制,通常是 6 个)。可是使用 HTTP2 以后就没必要要了,由于 HTTP2 采用多路复用,再多的资源也都可以进行并发请求。

  • 资源内联

在 HTTP1 中,咱们可会对一些小图片直接打包成 base64 格式,用来减小请求。但内联没法利用缓存优点,应具体状况具体分析。

  • 资源合并(雪碧图等)

因为多路复用的缘由,多个小图片能够并行请求,雪碧图也不是颇有必要了。

  • 禁用带 cookie 的域名

在 HTTP1 中,因为没法压缩首部,会启动一个无 cookie 的服务器专门用来存放某些静态资源,用来减小没必要要的 cookie 传输。在 HTTP2 中,首部信息会被 HPACK 算法优化,大大减小了首部字节,并且不用心增一个无 cookie 的服务器,因此建议取消掉禁用 cookie 域名的方式。

  • 资源预取

高数浏览器,之哟啊有可能就继续下载可缓存资源,并把这些资源缓存起来,这个仍是有必要。

<link rel="prefetch" href="xxx.css">

展望将来

一、HTTP 是使用 TCP 做为传输层的协议,因为 TCP 是可靠的,拥塞控制的协议,在进行一次链接时,会发生三次握手,断开链接时会有 4 次挥手,因此有人提出能够用 UDP 这种简单,快速的协议去代替。

  • Google 开发的 QUIC 是极快的 UDP 网络链接,提供了 HTTP2 等效的,多路复用,流量控制,TSL 等效的安全机制,以及 TCP 等效的链接语义、可靠性、拥塞机制。

二、TLS(传输层安全协议,用来实现 HTTPS)也在不断地进行改进。在 TLS1.3 版本中 新链接只须要一次往返(目前最少是三次),若是是恢复链接,则不须要往返延时。

相关文章
相关标签/搜索