创建连接
TCP三次握手:包括客户端想服务端发起一个SYN包,接着服务端返回对应SYN的ACK响应以及新的SYN包,然后客户端返回对应的ACK.
如果客户端发起HTTPS连接,它还需要进行传输层安全协议(TLS)协商;TLS用来取代安全套接层.
HTTP1的问题
1.队头阻塞:允许一次发送一组请求,但是只能按照发送顺序一次接受响应.现代浏览器一般针对单个域名开启6个连接.
2.使用拥塞接口:在接受方确认数据包之前,发送方可以发出的TCP包的数量.慢启动:每次响应成功则加倍发送的数据包,失败则减半发送的数据包.
3.消息首部臃肿
4.受限的优先级设置
5.第三方资源
Web性能的最佳实践(HTTP1)
1.DNS查询优化
a.限制不同域名的数量
b.保证低限度的解析延迟
c.在主体页面HTML或响应中利用DNS预取指定的域名如:
<link rel="dns-prefetch" href="//ajax.googleapis.com>
2.优化TCP连接
a.利用preconnect指令,连接在使用之前就已经建立好.如:
<link rel="preconnect" href="//fonts.example.com" crossorigin>
b.借助CDN,在距离请求用户很近的边缘端点上,请求就可以获得响应.
3.避免重定向
4.客户端缓存
浏览器支持
任何不支持HTTP2的客户端都将简单的退回到HTTP1
HTTP1的优化,对于HTTP2的建议:
1.资源合并:在HTTP2下并非必要.
2.去除域名拆分:域名拆分是为了利用浏览器对每个域名开启多个连接的能力,以便实现资源的并行下载,绕过http1的串行化下载的限制.而http2的设计意图是采用多路复用,充分利用单个socket连接,而拆分域名会违背这种意图.
3.去除禁用cookie:应该避免为这些资源单位设立域名,因为http2采用了HPACK算法首部压缩,会显著减少巨型cookie(尤其是当它们在先后请求之间保持不变)的字节数.与此同时,禁用cookie的域名需要额外的主机名称,这意味着将开启更多的连接,与http2意图违背.
HTTP2帧类型
0x0 DATA:传输流的核心内容
0x1 HEADERS:包含http首部,和可选的优先级参数
0x2 PRIORITY:指示或更改流的优先级和依赖
0x3 RST_STREAM:允许一端停止流
0x4 SETTINGS:协商连接级参数
0x5 PUSH_PROMISE:提示客户端,服务器要推送些东西
0x6 PING:测试连接可用性和往返延时(RTT)
0x7 GOAWAY:告诉另一端,当前端已结束
0x8 WINDOW_UPDATE:协商一端将要接收多少字节
0x9 CONTINUATION:用以扩展HEADER数据块
http2优先级
1.依赖关系:为客户端提供了一种能力,通过指明某些对象对另一些对象有依赖,告知服务器这些对象应该优先传输.
2.权重:让客户端告诉服务器如何确定具有共同依关系的对象的优先级.
服务器推送局限
https2中,服务器会在第一次请求中就向客户端推送信息,这样虽然可以节省时间,不过也可能推送了客户端不需要的信息.客户端确实可以发送RST_STREAM帧来拒绝服务器的PUSH_PROMISE帧,但是RST_STREAM并不会即可到达,所以服务器还是会发送一些多余的信息.
首部压缩HPACK,为什么不是GZIP?
因为GZIP也有泄露加密信息的风险.比如GRIME攻击,攻击者在请求中添加数据,观察压缩加密后的数据量是否会小于预期.如果变小了,攻击者就知道注入的文本和请求中的其他内容(比如私有的会话cookie)有重复.在很短的时间内,经过加密的数据内容就可以全部搞清楚.
http2比http1多做的工作:
1.窗口大小调节
2.依赖树构建
3.维持首部信息的静态/动态表
4.压缩/解压缩首部
5.优先级调整(http2允许客户端多次调整单一请求的优先级)
6.预先推送客户端尚未请求的数据流