前端与HTTP

本文整理在,个人github 上。欢迎Star。css

各版本的http

发展

在HTTP创建之初,主要是为了传输超文本标记语言(HTML)文档。随着时代的发展,也进行了若干次演进。下图是各个版本发布的时间轴。
html

目前为止,使用最为普遍的是http1.1http1.0应该比较少了,最新的是http2
这篇博文也主要,围绕着1.0、1.一、2.0三个版本进行介绍。前端

http/1.0

http1.0不会复用tcp连接,每次请求都会打开、断开一条连接。
若是您看过我前阵子整理的关于TCP的博文,您就会知道,TCP是有延迟响应机制的,每次请求并不会立刻返回。这算是http1.0性能很差的一个缘由吧。git

http/1.1

http/1.1当前普及程度最高的http版本。
到了http/1.1版本,tcp连接能够持久保持了(也就说,一段时间内,一个tcp连接会等到同一个域名下的全部资源加载完后再断开。)github

在保持tcp连接的基础上,引入了http管道的机制,差点实现了多路复用算法

http/1.1 without pipelining(不使用管道)

经过一条tcp连接请求资源,只有在上一个请求完成后,才能发出下一个请求。也就是上图描述的情形。浏览器

http/1.1 with pipelining(使用管道)

客户端不会等待响应,直接并发N个请求。可是,http/1.x有严格的串行返回响应机制。通俗的讲就是:请求时,不用等上一个完成;但响应时,必须严格按照顺序返回
经过开发者工具,你就能够观察到这一点。缓存

基于以上描述,使用“ HTTP 管道”技术时,万一第一个响应时间很长,那么后面的响应处理完了也没法发送,只能被缓存起来,占用服务器内存,这就是传说中的“队首阻塞(head of line blocking)”。
这也是http/1.x下,多数网络体验很差的缘由。性能优化

http/2.0

在介绍http/2.0以前,咱们来先看一份Akamai公司提供的一个官方演示服务器

这里用了361(19*19)张图片,分别使用http/1.1,http/2.0两种版本的协议进行对比。能够直观的感觉到,http/2.0比http/1.0快出5倍左右的速度。

考虑到您可能须要分别用开发者工具仔细查看下两个版本,我已经帮你找好了两个版本对应的连接。(不客气)


那http/2.0究竟引入了哪些机制、特性才达到目前的加速效果呢?简答的说能够归纳成。

  • 二进制分帧层
  • 多路复用
  • 首部压缩
  • 服务器推送(server Push)

二进制分帧层与多路复用

引入了二进制分帧层,就再也不是文本传输了,而是数据帧(二进制)。
注意:HTTP本来的语义,方法、动词、首部都不受影响。仅仅是传输期间的数据格式变化了。

http/2规定了10种不一样的帧。
如上图,分针层会把 开始行首部行分割到HEADERS帧正文实体分割到DATA帧。


TCP 链接在客户端和服务器间创建了一条运输的通道,能够双向通行,当一端要向另外一端发送消息时,会先把这个消息拆分红几部分(帧),而后经过发起一个流对这些帧进行发送,最后在另外一端将同一个流的帧从新组合。

这里涉及了如下概念。

流:已创建的链接上的双向字节流
消息:与逻辑消息对应的完整的一系列数据帧
帧:HTTP/2 通讯的最小单位,每一个帧包含帧首部

其中帧对数据进行顺序标识,这样浏览器收到数据以后,就能够按照序列对数据进行合并,而不会出现合并后数据错乱的状况。一样是由于有了序列,服务器就能够并行的传输数据,这就是流所作的事情。

HTTP/2对同一域名下全部请求都是基于流,也就是说同一域名无论访问多少文件,也只创建一路链接。一样Apache的最大链接数为300,由于有了这个新特性,最大的并发就能够提高到300,比原来提高了6倍!

首部压缩

在服务器和客户端各维护一个“首部表”,表中用索引表明首部名,或者首部键 - 值对,上一次发送两端都会记住已发送过哪些首部,下一次发送只须要传输差别的数据,相同的数据直接用索引表示便可。

首部压缩,能够解决http头臃肿的问题。

服务器推送(server Push)

服务器能够对一个客户端请求发送多个响应。也就是说,除了对最初请求的响应外,服务器还能够额外向客户端推送资源。

这里就涉及到了另外一个帧类型:PUSH_PROMISE帧。
举个栗子,当客户端请求index.html时,服务器会同时推送style.css,index.js对应的PUSH_PROMISE帧。客户端能够直接缓存起来。

基于http/2对前端性能优化的思考

我的以为前端的性能优化,应该主要从两个方面。加载速度流畅运行
原引,在网上看到的一段话:

网页不只应该被快速加载,同时还应该流畅运行,好比快速响应的交互,如丝般顺滑的动画等。


http/1.x的优化方案

固然,今天的主题是讨论网路协议,那咱们只谈加载速度。
基于http1.x的相关特性,可爱的前端们提出了不少颇具成效的优化方案。(精灵图,多域名加载等等)其中,比较著名的雅虎军规,不少人应道都知道,这里有一张整理好的图。

http/2的变革

在http/2的基础上,不少http/1.x要优化的问题,都不存在了。问题都不存在了,问题的优化方案也就不存在了。
这里插一句,我始终坚信的一个观点是:没有任何优化手段是不须要付出代价的。是药三分毒,无非是取舍罢了。

1.合并css、js与精灵图

在http/1.x时代,http并无最大程度上利用好tcp连接。虽然http/1.1里有了http管道,但其也带来了队首阻塞等问题,同时也要受队列大小的限制。因此咱们要经过合并文件的方式减小http连接数量。
不错,减小http请求数量的确能起到优化的做用,但与此同时,也有不少弊端:

  1. 全部文件合成一个大文件,那无论哪一个模块发生变动,都要总体更新,用户都要从新下载,没法继续使用缓存。
  2. 带来了额外的维护成本。印象比较深的是维护精灵图,稍微改一点,就得从新弄。

以上,就是”合并css方案"、“合并js方案”、“精灵图方案”的优点与弊端。

  • 在http/1.x基础上,明显优点>弊端,因此咱们使用这些方案。
  • 但http/2,它对tcp连接的利用程度已经有了飞跃性的提高。此时这些方案是否优点>弊端,就值得商榷了。笔者以为应该正好反过来。优点<弊端

2.分域名

在http/1.x基础上,分域名有两个好处。

  • 为了绕过浏览器对同一域名的最大管道限制。能够同时请求更多内容。
  • 同一域名下的请求报文,会匹配的站点的所有cookie,增大请求报文长度。而不少资源,好比图片、css是不须要cookie的。

在http/2上,对于这些问题

  • 本来就支持多路复用,不必分
  • 首部压缩机制,首部行大点,也就传一个。

3.接口合并

若是页面须要多种数据,咱们会尽可能将数据汇总到一个接口,以减小http请求数量。
这种作法,几乎违背了各类程序设计规范,好比“单一职责原则”等等,接口很难复用,维护成本高。
这种方案在http/2下,明显弊端>优点了。

参考文献

插一句《RFC7540》是官方对http2.0规格的描述,比较权威。

相关文章
相关标签/搜索