总之 HTTP/1.1 的性能一般般,后续的 HTTP/2 和 HTTP/3 就是在优化 HTTP 的性能。
HTTP/1.0默认使用「短连接」,如果需要改用长连接,则需要在请求头中加入 Connection: Keep-Alive,服务端收到响应后同样在响应头加上该字段。
而HTTP/1.1默认采用「长连接」,减少了TCP连接的重复建立和断开而造成的额外开销。
指在同一个 TCP连接 中,客户端可以连续发起多个请求,只要第一个请求成功发送,不必等待它的响应,就可以继续发送第二个请求,从而 减少了「整体响应时间」,也解决了「请求的队头阻塞」问题。
尽管管道网络传输使得请求可以连续发送(也就是解决了「请求的队头阻塞」),但响应却不一定会连续返回。
若某一个请求的响应由于某种原因无法及时返回,队中其他请求的响应将会被阻塞,这就是HTTP/1.1「响应的队头阻塞」问题。
客户端和服务端共同维护一张「头部信息表」,所有的头部字段都存入表中,并生成索引号。当下次请求或响应会用到同样的字段时,不再发送完整的头部文本,而是发送 该头部在表中的索引号,即「将完整的头部文本压缩成索引号」。
消息:这里指HTTP/2中的请求和响应;
帧:一个或多个「帧」组成一个「消息」;
HTTP / 1 的请求和响应报文,都是由起始行、首部和实体正文(可选)组成,各部分之间以文本换行符分隔。 HTTP/2 将请求和响应数据分割为更小的帧,并且它们采用二进制编码。
在HTTP/1.1中,数据传输使用「文本」的形式,在另一方接收到数据后,需要先将文本转成二进制,才能正常解析;
在HTTP/2.0中,数据传输使用「二进制」的形式,另一方接收后可以直接解析,大幅提升速度。
HTTP/2.0中,头信息和数据体都是二进制的,并且统称为「帧」,即「头信息帧」和「数据帧」。
多路复用,就是在同一个「TCP连接」中,将若干个「并发的消息」,拆解成若干个「二进制帧」并以不确定的顺序发送。另一方在接收到这些「二进制帧」后,按顺序将它们重新排序以得到「消息」的二进制形式,随后被直接解析。
由于消息都被拆分成帧,即使某一个请求无法及时作出响应,也不会阻塞其他的响应,会优先将能传的传回来,仍在处理的响应会被放在之后传输。
同一「流」的「帧」必须严格有序,不同「流」的帧可以乱序;
客户端的流编号为奇数,服务端的流编号为偶数。
在HTTP/1.1中,所有的资源都必须由客户端发起请求,才能返回给客户端;
而HTTP/2.0支持 主动推送(但又不是完全主动),比较常见的应用场景是:
客户端首次访问页面时,会发起请求获取HTML资源,服务端将会响应体中存放HTML,同时 在此次响应中通知客户端,即将有其他的资源被一并推送过来。
随后服务端在第二个流中,将后续即将被加载的js、css等文件发送给客户端,而客户端则会将这部分数据缓存起来,一会儿要用的时候,直接从缓存中获取。