HTTP 1.0 是 1996 年发布的,奠定了 web 的基础。时隔三年,1999 年又发布了 HTTP 1.1,对功能上做了扩充。之后又时隔十六年,2015 年发布了 HTTP 2.0。
同学们肯定会觉得,隔了这么长时间,而且还从版本号安卓性能优化还从 1 到了 2,那肯定有很多的新功能。其实不是的,HTTP 2.0 没有没有功能上的新增,只是优化了性能。
为什么要这么大的版本升级来优化性能,HTTP 1.1 的性能很差么?
那我们就来看下 HTTP 1.1三次握手四次挥手详解 有什么问题:
HTTP 1.1 的问题
我们知道,HTTP 的下层协议是 TCP安卓性能优化,需要经历三次握手才能建立连接。而 HTTP 1.0 的时候一次请求和响应结束就会断开链接,这样下次请求又要重新三次握手来建立连接。
为了减少这种建立 TCP 链接的消耗,HT状态机的作用TP 1.1 支持了 keep-索引的优缺点alive性能优化的方法,只要请求或响应头带上 Conn浏览器ection: keep-alive,就可以告诉对方前端性能优化先不要断开链接,我之后还要用这个链接发消息。当需要断开的时候,再指定 Connection: close 的 header。
这样就可以用同一个 TCP 链接进行多次 HTTP 请求响应了:
但这样虽然减少了链接的建立,在性能上却有问题,下次请求得等上一个请求返回响应才能发出。
这个问题有个名字,叫做队头阻塞,很容易理解,因为多前端性能优化个请求要排队嘛,队前面的卡住了,那后面的也安卓性能优化就执行不了了。
怎么解决这个问题呢?
HTTP 1.1 提出了管道的概念,就是多个请求可以并行发送,返回三次握手和四次挥手面试题怎么回答响应后再依次处理。
也就是这样:
其实这样能索引的作用部分解决问题,但是返回的响应依然要依次处理,解决不了队头阻塞的问题。
所以说管道化是比较鸡肋的一个功能,现在绝大多索引图数浏览器都默认关闭了,甚至都不支持。
那还能怎么解决这个队头阻塞的问题呢?
开多个索引失效队不就行了。
浏览器一般会同一个域名建立 6-8 个 TCP 链接,也就是 6-8 个队,如果一个队发生队头阻塞了,那就放到其他的队里。性能优化
这样就缓解了队头阻塞问题。
我们写的网页想尽快的打开就要利用这一点,比如把静态资源部署在不同的域名下。这样每个域名都能并发 6-8 个下载请求,网页打开的速度自然就会快很多。
这种优化手段叫做“域名分片”,CDN 一般都支持这个。
除了队头阻塞的问题,HTTP 1.1 还有没有别的问题?
有,比如索引失效 header 部分太大了。
不知道大家有没有感觉,就算你内容只传输几个字符,也得带上一大堆 header:
而且这前端性能优化些 header 还都是文本的,这样占据的空状态机编程间就格外的大。
比如,如果是二进制,表示 true 和 false 直接 1 位就行了,而文本的那就得经过编码,“true” 就占了 4 个字节,也就是 32页面性能优化 位。那就是 32 倍的差距呀!
所以呢,HTTP 1.1 的时候,我们就要尽量避免一些小请求,因为就算请求的内容很少,也会带上一大段 heade状态机模式r。特别是有 cookie浏览器下载 的情况,问题格外明显。
因此,我们的网页就要做打包,也就是需要打包工具把模块合并成多个 chu三次握手和四次挥手nk 来前端性能优化加载。需要把小图片合并成大图片,通过调整 backgroun汽车性能优化d:position 来使用。需要把一些 cs品悟性能优化s、图片等内联。而且静态资源的域名也要禁止携带 cookie。
这些都是为了减少请求次数来达到提高加载性能的目的。
而且 HTTP 的底层是 TCP,其实是可以双向传输数据的,现在却只能通过请求—响应这种一问一答的方式,并没有充分利用起 TCP 的能力。
聊了这么状态机图多,不知道大家是否有优化它的冲动了。
也就是因为这些问题,HTTP 2.0 出现了,做了很多性能优化,基本解决了上面那些问题。
那 HTTP2 都做了哪些优化呢?
HTTP 2浏览器的历史记录在哪.0 的优化
先不着急看 HTTP 2.0 是怎么优化的,就上面那些问题来说,如果让我们解决,我们会怎么解决?
比如队头阻塞的问题,也就是第二个响应要等第一个响应处理完之后才能处理。怎么解决?
这个很容易解决呀,每个请求、响应都加上一个 ID,然后每个响应和通过 ID 来找到它对应的请求。各回各家三次握手过程,自然就不用阻塞的等待了。
再比如说 header 过大这个问题,怎么解决?
文本传输太占空间,换成二进制的是不是会好很多。
还有,每次传输都三次握手详细过程有很多相同的 header,能不能三次握手四次挥手简述建立一张表,传的时候只传输下标就行了。
还有,body 可以压缩,那 header 是不是可以压缩。
这样处理之后,应该会好很多。
那没有充分利用 TCP 的能力,只支持请求–响应的方式呢?
那就支持服务端主动推送呀,但是客户端可以选择接收或者不接收。
上面是我们对这些问状态机设计模式题的解决方案的思考,我们再来看看 HTTP2 是怎么解决这些问题的:
HTTP2 确实是通过 ID 把请求和响应浏览器怎么打开网站关联起来了,它把这个概念叫做流 stream。
而且我们之前说了 header 需要单独的优化嘛,汽车性能优化所以把 header 和 body 部分分开来传送,叫做不同的帧 frame。
每个帧都是这样的格式:
payload 部分是传输的内容这没啥可说的。
header 部分最开始是长度,然后是这个帧的类型,有这样几种类型:
- SETTINGS 帧:配置信息,比如最大帧 si浏览器下载ze,是否支持 server push 等。
- HEADERS 帧:请求或响应的 header
- DAT索引的优缺点A 帧:请求或响应的 body
- CONTINUATION 帧:一个帧不够装的时候,可以分帧,用这个可以引用上一个帧。
- PUSH_PROMISE 帧:服务端推送数据的帧
- END_STREAM 帧:表示流传输结束
- RST_STREAM 帧,用来终止当前流
这状态机设计模式几种帧里面 HEA浏览器的历史DERS 和 DATA 帧没啥可说的。
SETTING 帧状态机设计模式是配置信息,先告诉对方我这里支持什么,帧大小设置为多大等。
帧大索引的作用小是有个上限的浏览器的历史记录在哪,如果帧太大了,可以分成多个,这时候帧类型就是 CONTINUATION(继续)。也很容易理解。
HTTP2 确实是支持服务端推送的,这时候帧类型也是单独的,叫做 PUSH_PROMISE。
流是用来传输请求响应或者服务端推送的,那传输完毕的时候就可以发送 END_STREAM 帧来表示传输完了,然后再传输状态机的作用 RST_STREAM 来结束当有限状态机前流。
帧的类型讲完了,我们继续往后看,后面还有个 flags 标志位,这个状态机的作用在不同的帧类型里会放不同的内容:
比如 header 帧会在 flag索引失效的几种情况s 中设置优状态机图先级,这样高优先级的流就可以更早的被处理。
HTTP 1.1 的时候都是排队处理的,没什有限状态机么优先级可言,而 HTTP 2.0 通过流三次握手详细过程的方式实现了请求的并发,那自然就可以控制优先级了三次握手详细过程。
后面还有个 R,这个现在还没啥用,是一个保留的位。
再后面的流标识符就是 stream id 了,关联同一个流的多个帧用的。
帧的格式讲索引失效的几种情况完了,大家索引超出了数组界限什么意思是不是有点晕晕的。确实,帧还是有很多种的。这些帧之间发送顺序也不同,不同的帧会在不同状态下发送,也会改变流的状态。
我们来看下流的状态机,也就是流收到什么帧会进入什么状态,并且在什么状态下会发手机性能优化送什么帧:
(看不明白可以先往后看)
刚开始,流是 idle 状态,也就是空闲。
收到或发送 HEADERS索引页是哪一页 帧以后会进入 open 状态。
oep性能优化的方法n 状态下可以发送或接收多次 DATA 帧。
之后发送或接收 END_STREAM 帧进入 half_closed 状态。
half_closed 状态下收到或者发送 RST_STREAM 帧就关闭流。
这个流程很容易理解,就是先发送 HEADER,再发送 DATA,之后告诉对方结束,也就是 END_STREAM,然后关闭 RST_STR状态机设计模式EAM。
但是 HTTP2 还可以服务浏览器网站删除了怎么恢复端推送呀,所以还有另一条状态转换流程。
流刚开始是 idle 状态。
接收到 PUSH_PROMISE 帧,也就电脑性能优化是服有限状态机务端推送过来的数据,变为 reserved 状态有限状态机。
reserved 状态可以再发索引是什么意思送或接收状态机的作用 header,之后进入 half_clo索引页是哪一页sed 状态。
后面的流程是一样的电脑性能优化,也是 END_STREAM 和 RST_浏览器怎么打开网站STREAM。
这个流程是 HTTP2 特有的,也就是先推送数据,再发送 headers,然后结束流。
这就是 http2 发送一次请求、响应,状态机编程或者一次服务端推送的流程,都是封装在一个个流里面的。
流和流之间可以并发,还可以设置优先级,这样自然就没有了队头阻塞的问题,这个特性叫做多路复用。也就是复用同一个链接状态机模式,建立起多条通路(流)的意思。
而且传输的 header 帧也是经过处理的,就像我们前面说的,会用二浏览器怎么打开网站进制的方式表示,用做压缩,而且前端性能优化压缩算法是专门设计js性能优化的,叫做 HPACK:
两端会维护一个索引表,状态机的作用通过下标来标识 header,这样传输量就少了不少:状态机模式
首先,header 里其实不止有 header,还有一行 GET xxx/xxx 的请求行,和 200 xxx 的响应行,为了统一处理,就换成了 :host :path 等 header 来表示。
这样发送的时候只需要发送下标就行:
比如 :method: get 就只需要发送个 2: get。
这个编码也是根据频率高低来设置的,频率高的用小编码,这种方式三次握手四次挥手详解叫做哈夫曼编码。
这样就实现了 header 的压缩。
至此, HTTP2.0 的主要特性就讲完了,也就是多路复用,服务端推送,头部压缩,二进制传输。
最主要的特性是多品悟性能优化路复用,也就是浏览器怎么打开网站流和帧,流在什么状态下发送什么帧。其他的特性是围绕这个来设计的。
回过头来看一下 HTTP1.1 的问题是否都得三次握手和四次挥手面试题怎么回答到了解决:
队头阻塞:通过流的来标识请求、响应,同一个流的分为多个帧来传输,多个流之间可以索引页是哪一页并发,不会相互阻塞。
he三次握手四次挥手过程ader 太大:通过二进制的形式,加上 HPACK的压缩算法,使得 header索引失效的几种情况 减小了很多。
没有充分利用 TCP 的特性:支持了服务端推送。
这样看来,HTTP2.0 确实解决了 HTTP 1.1 的问题。
看起来,HTTP 2.0 已经很完美了?
其实不是的,虽然 HTTP 层面没有了队头阻塞问题,多个请求响应可以并行处理。但是同一个流的多个帧还是有队头阻塞问题,以为你 TCP 层面会保证顺序处理,丢失了会重传,这就导致汽车性能优化了上一个帧没收到的话,下一个帧是处理不了的。
这个问题是 TCP 的可靠传输的特性带索引图来的,所以想彻底解决队头阻塞问题,只能把 HTTP 的底层传输协议换掉了。
这就是 HTTP3 做的事情了,它的传输层协议换浏览器哪个好成了 UDP。当然,现在 HTTP3 还不是很成熟,我们先重点关注 HTTP2 即可。
总结
1996 年发布 HTTP 1.0,1999 年 HTTP 1.1,2015 年 HTTP 2.0。
1.1 和 2 之间间隔了 16 年,确实改变了很多,但三次握手过程只是性能方面的。
1.1 的问题是第二个请求要等第一个响应之后才能发出,就算用索引的优缺点了管道化,多个响应之间依然也会阻塞,这就是“队头阻塞”问题。
而且 header 部分太大了,性能优化还是纯文本的,可能比 body浏览器的历史记录在哪 部分传的都多。
针对 1.1 的队头阻塞问题,我们会做域名分片,状态机的作用针对 header 过大的问题,我们会减少请求次数,也就是有限状态机打包分 chunk、索引超出了数组界限什么意思资源内联、雪碧图、静态资源请求禁止 cookie 等三次握手四次挥手简述优化策略。
HTTP 2.0 解决了 1.1 的这些问题,通过多路复用,也就状态机模式是请求和响应在一个流里,通过同一个流 id 来关联多个帧的方式来传输数三次握手过程据。多个流可以并发。
我们状态机的概念看了帧的格式,有长度、类型、stream id、falgs 还有 payload 等部分。
帧的类型还是挺多的,有 HEADRS、DATA、SETTINGS、PUSH_PROMISE、END_STREAM、EST_STREAM、等。
这些帧类型之间也不是毫无关联的,流在不同的状态下会发送、接收不同的帧,而且发送、接收不同的帧也会进入不同的状态。
理解 HTTP2.0 的 stream 就要理解这样的一个状态流转流程。
此外,HTTP 2.0 通过单独设计的 HPACK 算法对 header 做了压缩,也支持服务端推送。而且内容是通过二进制传输的,解浏览器怎么打开网站决了 HTTP 1.1 的问题。
但是 HTTP 2.0 的底层是 TCP,它的可靠传输的特性使得同一个流内的多个帧依然是顺序传输的,品悟性能优化依然有队头阻塞问题。也是因为 HTP状态机的作用 3 把底层协议换成 UDP。
虽然还是有一些问题,但 HTTP 2.0 已经基本上把 HTTP 1.1 的各方面性能不好的点都优化到了极致,是很有浏览器历史上的痕迹在哪里意义的一次版索引的优缺点本升级。