HAR文件:记录每一次请求的细节,方便还原浏览器打开的行为。
Pingdom:网络的性能分析。
Caniuse:检测网络的特性。
http0.9
时间:1991年
目标:在网络之间传递HTML超文本内容,用于学术交流。
实现:基于TCP的请求响应模式
- 请求:只有请求行(get请求),没有请求头和请求体。
- 响应:只返回响应数据(字符流),没有响应头。
缺陷:具有局限性,无法满足复杂的需求。
http1.0
时间:1996年
目标:不仅能够传输HTML文件,还能够传输JavaScript、CSS、图片、视频、音频等不同类型的文件,满足新兴网络的发展。
实现:添加请求头和响应头进行协商。
- 请求:
accept: text/html //期待返回的文件类型
accept-encoding: gzip, deflate, br //浏览器支持的压缩方式
accept-Charset: ISO-8859-1,utf-8 //期待返回的编码格式
accept-language: zh-CN,zh //浏览器要显示的语言
- 响应:
content-encoding: br //采用的压缩方式
content-type: text/html; charset=UTF-8
其他特性:
HTTP/1.0 除了对多文件提供良好的支持外,还依据当时实际的需求引入了很多其他的特性,这些特性都是通过请求头和响应头来实现的。下面我们来看看新增的几个典型的特性:
- 状态码:有的请求服务器可能无法处理,或者处理出错,这时候就需要告诉浏览器服务器最终处理该请求的情况,这就引入了状态码。状态码是通过响应行的方式来通知浏览器的。
- Cache机制:为了减轻服务器的压力,在 HTTP/1.0 中提供了 Cache 机制,用来缓存已经下载过的数据。
- 用户代理:服务器需要统计客户端的基础信息,比如 Windows 和 macOS 的用户数量分别是多少,所以 HTTP/1.0 的请求头中还加入了用户代理的字段。
缺陷:
- 短连接:每次请求都要建立连接,释放连接。造成无用的开销和延迟。
http1.1
时间:1999年
目标:对http1.0进行大量的优化。
实现:
-
长连接:使用keep alive(声明重用上一个连接), 建立一个长连接,可以重用,不会马上断开。此时http请求中会携带一个Http请求头:Connection:keep-alive,现在大部分的web服务器都默认支持tcp长连接,也就是网页中的请求不携带Connection:keep-alive请求头,默认就是长连接请求,如果不想支持长连接的话,需要显示的添加Connection:closed请求头。
-
管道化:允许客户端在已发送的请求收到服务端的响应之前发送下一个请求,同一个tcp连接中可以同时发送多个http请求,也就是并发,但是在响应的时候,必须排队响应,谁先到达的谁先响应,相比不支持管道化的http请求确实提高了效率,但是还是没有解决队头堵塞的问题。由于一些 限制现代浏览器默认都关闭了管道化。
-
并行TCP连接:同时打开并行的TCP连接(最多6~8个)。有些web优化方案中还会突破6到8的限制,那就是域名切片,因为长连接是针对的同一个域名,那么如果开发人员将资源分布在不同的域名上,那么长连接的数量也是可以被突破的。
-
引入虚拟主机、Cookie、安全机制等支持,优化缓存策略。
缺陷:
- 队头阻塞:需要等待前面的请求返回后,才能发起下一个请求,某个请求没有及时返回,就会堵塞后面的所有请求,这就是著名的队头阻塞。
http2
时间:2015年
目标:为了优化传输性能,降低延时,提高吞吐量。
实现:
- 二进制分帧层:数据经过会被转换为一个个带有请求ID编号的帧。服务端将ID编号相同的合并为完整的请求信息。反之亦然。会存在数据包级别的队头阻塞。有一个包丢失,整个TCP连接就处于暂停状态。
- 多路复用
- 头部压缩
- 设置请求的优先级
- 服务端主动推送
总结:一个域名只使用一个TCP长连接,这样整个页面的资源下载只需要一次慢启动,同时也避免了多个TCP连接竞争带宽所引发的问题,消除http1.1中的队头阻塞问题。
http3
时间:2019
目标:避开TCP队头阻塞、TCP延迟、TCP僵化问题。
实现:基于UDP的+快速握手+可靠性+TLS+多路复用+有序交付=QUIC
参考文献:
白话http队头阻塞
极客时间—浏览器工作原理与实践