相比http1.1性能有基于以下优化点的提升
二进制分帧*层
http1.1传输采用文本格式,http2.0把数据拆成了两个帧,分别是HEADERS帧和DATA帧,并且采用二进制编码。这是性能提升主要手段
二进制分帧
多路复用
HTTP1.x存在head of line blocking,也就是一个TCP连接上只能发送一个请求,前面请求没有完成,后续的请求都要排队。以及多个TCP建立成本高,还存在慢启动问题。
不过即使有多路复用,还是会排队,因为请求过多会超过服务器可以承受的能力,tcp层的流量控制会帮忙解决这个问题。
头部压缩
请求的头部字段大部分是相同的,例如user-agent,cookie等,HTTP2采用HPACK压缩格式压缩头部。头部压缩需要再浏览器和服务器中:
- 维护一份相同的静态字典,包含常见的头部名称
- 维护一份相同的动态字典,可以动态添加内容
-
通过Huffman编码对传输的头部字段进行编码
HTTP2的静态字典
基于头部压缩能力,传输是只需要传输静态字典里对应的索引值,一个字节搞定。
对于静态字典里没有的内容,第一次传输时需要带上,浏览器和服务器就会把它加到动态字典,后续传输就可以用索银子代替,一个字节搞定。
服务器推送
服务器端推送使得服务器可以预测客户端需要的资源,主动推送到客户端。
例如:客户端请求index.html,服务器端能够额外推送script.js和style.css。
实现原理就是客户端发出页面请求时,服务器端能够分析这个页面所依赖的其他资源,主动推送到客户端的缓存,当客户端收到原始网页的请求时,它需要的资源已经位于缓存。
针对每一个希望发送的资源,服务器会发送一个PUSH_PROMISE帧,客户端可以通过发送RST_STREAM帧来拒绝推送(当资源已经位于缓存)。这一步的操作先于父响应(index.html),客户端了解到服务器端打算推送哪些资源,就不会再为这些资源创建重复请求。当客户端收到index.html的响应时,script.js和style.css已经位于缓存。
看到这里会有一个疑问,HTTP2既然可以服务器推送,那么是否可以替代websocket,答案是不可以。HTTP2虽然支持服务器推送资源到客户端,但那不是应用程序可以感知的,主要是让浏览器(用户代理)提前缓存静态资源,所以我们不能指望HTTP2可以像WebSocket建立双向实时通信。
帧*
流(stream):建立的TCP连接上的双向字节流,可以承载一个或多个消息。
消息(message):一个完整的HTTP请求或是响应,有一个或多个帧组成,特定消息的帧在通过留上发送,也就是说一个HTTP请求或响应只能在一个流上发送。
帧(frame):通讯的基本单元。
网友评论