http/2
HTTP/1.1 版的头信息肯定是文本(ASCII编码),数据体可以是文本,也可以是二进制。HTTP/2 基于SPDY设计的,则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为”帧”(frame):头信息帧和数据帧。
-
与HTTP/1.1相比,HTTP/2新增加了很多特性,例如:
-
连接复用(可以使用单个TCP连接传输多个文件,缩短TCP握手的时间,并且可以不按顺序一一响应,避免“队头堵塞”),也可以避开浏览器同域名下的连接限制。
-
HTTP Header缩短 – 客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。(这也就意味着减少传输,加快速度)
首先协议里预设了一个静态字典,用来表示常用的头部字段,比如就是 method get。以前需要把完整的key-value对发过去,现在只需要把一个数字发过去,大小大幅缩小。
其次,客户端和服务端会共同维护一个动态表,动态表用来干啥呢?举个例子,比如useragent, 每个用户的useragent值是不一样的,没法放到静态表中去约定。但是对于同一个用户会话,useragent是不会改变,这样的值,就由客户端和服务端协商决定存入动态表,这样第一次传输过去之后,以后就只需要传入动态表中的一个编码就行了,图中的62和63就是这样的情况。连接中发送的请求越多,就越能丰富动态表中的值,越到后面,请求性能越好(佐证了域名散列的方式不可取)
还有一类情况,值总是变来变去,也没法保存到动态表中。这时候,只能直接压缩了。在h2中采用的是Huffman压缩算法,能把数字或字符最短压缩到5个字节,最大压缩率是37.5%
-
Server Push(服务器推送,将以往的客户端单方向请求服务器变成双向交互)
-
强制加密(这个其实是Chrome和Firefox自己加入的特性,HTTP/2协议只允许通过SSL连接)
-
http/1.1边界根据content-length或者长度为0的chunk划分;http/2对数据包标记来划分边界
-
-
数据流
HTTP/2 将每个请求或回应的所有数据包,称为一个数据流(stream)。每个数据流都有一个独一无二的编号。数据包发送的时候,都必须标记数据流ID,用来区分它属于哪个数据流。客户端发出的数据流,ID为奇数,服务器发出的,ID为偶数。
数据流发送到一半的时候,客户端和服务器都可以发送信号(RST_STREAM帧),取消这个数据流。客户端还可以指定数据流的优先级。优先级越高,服务器就会越早回应。
其他优化技巧
-
DNS 预获取
加了 dns-prefetch 可以提前去解析资源的域名,这样可以减少网络请求时间。
<meta http-equiv="x-dns-prefetch-control" content="on"> <link rel="dns-prefetch" href="http://www.test.com/">