从一个网页的加载周期谈性能优化之-网络

870 阅读26分钟

持续更新!!!各位小伙伴大家好,我们今天跟大家介绍一下性能分析,说到性能优化经常在面试中被面试官问到,很多小伙伴们回答是压缩文件、动静分离、雪碧图、懒加载、数据缓存、按需加载……,一下子说出了很多性能优化的方法,这的确是性能优化的方法,随便百度一下,都能搜索到很多答案, 然而你确定这就是面试官想要的答案吗?

说到性能优化我们不得不提这张图⬇️,这张图是我们性能优化的参考,如果这张图我们都不知道,那我们谈性能优化其实都是在耍流氓……首先我们要分析一个网页分为加载前加载后,解析中,渲染等几个过程

preformance.png

performance.timing

  1. navigationStart:当前浏览器窗口的前一个网页关闭,发生unload事件时的Unix毫秒时间戳。如果没有前一个网页,则等于fetchStart属性。
  2. unloadEventStart:如果前一个网页与当前网页属于同一个域名,则返回前一个网页的unload事件发生时的Unix毫秒时间戳。如果没有前一个网页,或者之前的网页跳转不是在同一个域名内,则返回值为0。
  3. unloadEventEnd:如果前一个网页与当前网页属于同一个域名,则返回前一个网页unload事件的回调函数结束时的Unix毫秒时间戳。如果没有前一个网页,或者之前的网页跳转不是在同一个域名内,则返回值为0。
  4. redirectStart:返回第一个HTTP跳转开始时的Unix毫秒时间戳。如果没有跳转,或者不是同一个域名内部的跳转,则返回值为0。
  5. redirectEnd:返回最后一个HTTP跳转结束时(即跳转回应的最后一个字节接受完成时)的Unix毫秒时间戳。如果没有跳转,或者不是同一个域名内部的跳转,则返回值为0。
  6. fetchStart:返回浏览器准备使用HTTP请求读取文档时的Unix毫秒时间戳。该事件在网页查询本地缓存之前发生。
  7. domainLookupStart:返回域名查询开始时的Unix毫秒时间戳。如果使用持久连接,或者信息是从本地缓存获取的,则返回值等同于fetchStart属性的值。
  8. domainLookupEnd:返回域名查询结束时的Unix毫秒时间戳。如果使用持久连接,或者信息是从本地缓存获取的,则返回值等同于fetchStart属性的值。 9.connectStart:返回HTTP请求开始向服务器发送时的Unix毫秒时间戳。如果使用持久连接(persistent connection),则返回值等同于fetchStart属性的值。
  9. connectEnd:返回浏览器与服务器之间的连接建立时的Unix毫秒时间戳。如果建立的是持久连接,则返回值等同于fetchStart属性的值。连接建立指的是所有握手和认证过程全部结束。
  10. secureConnectionStart:返回浏览器与服务器开始安全链接的握手时的Unix毫秒时间戳。如果当前网页不要求安全连接,则返回0。
  11. requestStart:返回浏览器向服务器发出HTTP请求时(或开始读取本地缓存时)的Unix毫秒时间戳。
  12. responseStart:返回浏览器从服务器收到(或从本地缓存读取)第一个字节时的Unix毫秒时间戳。
  13. responseEnd:返回浏览器从服务器收到(或从本地缓存读取)最后一个字节时(如果在此之前HTTP连接已经关闭,则返回关闭时)的Unix毫秒时间戳。
  14. domLoading:返回当前网页DOM结构开始解析时(即Document.readyState属性变为“loading”、相应的readystatechange事件触发时)的Unix毫秒时间戳。
  15. domInteractive:返回当前网页DOM结构结束解析、开始加载内嵌资源时(即Document.readyState属性变为“interactive”、相应的readystatechange事件触发时)的Unix毫秒时间戳。
  16. domContentLoadedEventStart:返回当前网页DOMContentLoaded事件发生时(即DOM结构解析完毕、所有脚本开始运行时)的Unix毫秒时间戳。
  17. domContentLoadedEventEnd:返回当前网页所有需要执行的脚本执行完成时的Unix毫秒时间戳。
  18. domComplete:返回当前网页DOM结构生成时(即Document.readyState属性变为“complete”,以及相应的readystatechange事件发生时)的Unix毫秒时间戳。
  19. loadEventStart:返回当前网页load事件的回调函数开始时的Unix毫秒时间戳。如果该事件还没有发生,返回0。
  20. loadEventEnd:返回当前网页load事件的回调函数运行结束时的Unix毫秒时间戳。如果该事件还没有发生,返回0。

从输入url到看到页面的过程

先从网络层来看一个网页的加载方式

cache.png

检查缓存 > DNS解析 > 发送HTTP请求 > 将响应数据提交给渲染进程处理 > 构建DOM > 样式计算 > 布局 > 分层 > 绘制 > DOM渲染

DNS预计解析

DNS-prefetch (DNS 预获取) 是尝试在请求资源之前解析域名。这可能是后面要加载的文件,也可能是用户尝试打开的链接目标。当浏览器从(第三方)服务器请求资源时,必须先将该跨域域名解析为 IP 地址,然后浏览器才能发出请求。此过程称为 DNS 解析。DNS 缓存可以帮助减少此延迟,而 DNS 解析可以导致请求增加明显的延迟。对于打开了与许多第三方的连接的网站,此延迟可能会大大降低加载性能。

请记住以下三点:

  1. 首先,dns-prefetch 仅对跨域域上的 DNS 查找有效,因此请避免使用它来指向您的站点或域。这是因为,到浏览器看到提示时,您站点域背后的 IP 已经被解析。
<link rel="dns-prefetch" href="https://fonts.googleapis.com/">
  1. 其次,还可以通过使用 HTTP 链接字段将 dns-prefetch(以及其他资源提示)指定为 HTTP 标头
    Link: <https://fonts.gstatic.com/>; rel=dns-prefetch
  1. 考虑将 dns-prefetch 与 preconnect(预连接)提示配对。尽管 dns-prefetch 仅执行 DNS 查找,但preconnect 会建立与服务器的连接。如果站点是通过 HTTPS 服务的,则此过程包括 DNS 解析,建立 TCP 连接以及执行 TLS 握手。将两者结合起来可提供进一步减少跨域请求的感知延迟的机会。您可以安全地将它们一起使用,
<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin>
<link rel="dns-prefetch" href="https://fonts.gstatic.com/">

资源预请求

preload

preload和prefetch的出现为我们提供了可以更加细粒度地控制浏览器加载资源的方法。 link标签的preload是一种声明式的资源获取请求方式,用于提前加载一些需要的依赖,并且不会影响页面的onload事件,使用方式如下:

<link rel="preload" as="script" href="test.js" onload="onLoadSuccess()" onerror="onloadError()" />
// css加载后立即生效
<link rel="preload" as="style" href="test.css" onload="this.rel=stylesheet" /> 

其中,rel属性值为preload;as属性用于规定资源的类型,并根据资源类型设置Accep请求头,以便能够使用正常的策略去请求对应的资源;href为资源请求地址;onload和onerror则分别是资源加载成功和失败后的回调函数;

as的值可以取style、script、image、font、fetch、document、audio、video等;如果as属性被省略,那么该请求将会当做异步请求处理;另外,在请求跨域资源时推荐加上crossorigin属性,否则可能会导致资源的二次加载(尤其是font资源):

<link rel="preload" as="font" href="www.font.com" crossorigin="anonymous" />
<link rel="preload" as="font" href="www.font.com" crossorigin="use-credentials" />

preload特点

  1. preload加载的资源是在浏览器渲染机制之前进行处理的,并且不会阻塞onload事件;
  2. preload可以支持加载多种类型的资源,并且可以加载跨域资源;
  3. preload加载的js脚本其加载和执行的过程是分离的。即preload会预加载 相应的脚本代码,待到需要时自行调用;

prefetch

prefetch是一种利用浏览器的空闲时间加载页面将来可能用到的资源的一种机制;通常可以用于加载非首页的其他页面所需要的资源,以便加快后续页面的首屏速度;

prefetch特点

pretch加载的资源可以获取非当前页面所需要的资源,并且将其放入缓存至少5分钟(无论资源是否可以缓存);并且当页面跳转时,未完成的prefetch请求不会被中断;

defer && defer

<script src='xxx.js'></script>
<script src='xxx.js' async></script>
<script src='xxx.js' defer></script>

defer 和 defer 在网络读取(下载)这块儿是一样的,都是异步的(相较于 HTML 解析) 它俩的差别在于脚本下载完之后何时执行,显然 defer 是最接近我们对于应用脚本加载和执行的要求的 关于 defer,下图未尽之处在于它是按照加载顺序执行脚本的,这一点要善加利用 async 则是一个乱序执行的主,反正对它来说脚本的加载和执行是紧紧挨着的,所以不管你声明的顺序如何,只要它加载完了就会立刻执行

仔细想想,async 对于应用脚本的用处不大,因为它完全不考虑依赖(哪怕是最低级的顺序执行),不过它对于那些可以不依赖任何脚本或不被任何脚本依赖的脚本来说却是非常合适的,最典型的例子:Google Analytics

defer.png

script 标签JS 执行顺序是否阻塞解析 HTML
script在 HTML 中的顺序阻塞
async网络请求返回顺序可能阻塞,也可能不阻塞
defer在 HTML 中的顺序不阻塞

CDN

CDN英文全称Content Delivery Network,中文翻译即为内容分发网络。 CDN 的基本技术思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,提升内容传输的速度和稳定性。 CDN 加速则是把原服务器上数据复制到其他服务器上,如网站上传的图片、视频,以及引入的Js、css 等文件等,在开启CDN 后,不同地区用户访问会分配不同的服务器。

cdn.png

CDN获取的方法一般有两种,一种是主动探测,一种是协议交互。

  1. 主动探测: 针对SLB设备和Cache设备没有协议交互接口的情况,通过ping等命令主动发起探测,根据返回结果分析状态。
  2. 协议交互: 即SLB和Cache根据事先定义好的协议实时交换运行状态信息,以便进行负载均衡。比较而言,协议交互比探测方式要准确可靠,但是目前尚没有标准的协议,各厂家的实现一般仅是私有协议,互通比较困难。

缓存

http缓存机制主要在http响应头中设定,响应头中相关字段为Expires、Cache-Control、Last-Modified、Etag。

WechatIMG171.jpeg 浏览器缓存分为强缓存和协商缓存

express.png 打开浏览器F12查看Network 看到size disk cache memory cache

  1. memory cache : 不访问服务器,一般已经加载过该资源且缓存在了内存当中,直接从内存中读取缓存。浏览器关闭后,数据将不存在(资源被释放掉了)
  2. disk cache: 不访问服务器,已经在之前的某个时间加载过该资源,直接从硬盘中读取缓存,关闭浏览器后,数据依然存在,

优先访问memory cache,其次是disk cache,最后是请求网络资源

强缓存

强缓存:浏览器不会像服务器发送任何请求,直接从本地缓存中读取文件并返回Status Code: 200 OK

参数
  1. Expires:过期时间,如果设置了时间,则浏览器会在设置的时间内直接读取缓存,不再请求
  2. Cache-Control:当值设为max-age=300时,则代表在这个请求正确返回时间(浏览器也会记录下来)的5分钟内再次加载资源,就会命中强缓存。

协商缓存

协商缓存: 向服务器发送请求,服务器会根据这个请求的request header的一些参数来判断是否命中协商缓存,如果命中,则返回304状态码并带上新的response header通知浏览器从缓存中读取资源;

参数
  1. Etag/If-None-Match:

    1. Etag是属于HTTP 1.1属性,它是由服务器(Apache或者其他工具)生成返回给前端,用来帮助服务器控制Web端的缓存验证。Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的
    2. If-None-Match:当资源过期时,浏览器发现响应头里有Etag,则再次像服务器请求时带上请求头if-none-match(值是Etag的值)。服务器收到请求进行比对,决定返回200或304
  2. Last-Modifed/If-Modified-Since:

    1. Last-Modified:浏览器向服务器发送资源最后的修改时间
    2. If-Modified-Since:当请求过期时(浏览器判断Cache-Control过期),发现响应头具有Last-Modified声明,则再次向服务器请求时带上头if-modified-since,表示上次请求时间。服务器收到请求后发现有if-modified-since则与被请求资源的最后修改时间进行对比(Last-Modified),若最后修改时间较新(大),说明资源又被改过,则返回最新资源,HTTP 200 OK;若最后修改时间较旧(小),说明资源无新修改,响应HTTP 304 走缓存。

注意:

Last-Modifed/If-Modified-Since的时间精度是,而Etag可以更精确; Etag优先级是高于Last-Modifed的,所以服务器会优先验证Etag; Last-Modifed/If-Modified-Since是http1.0的头字段。

WechatIMG172.jpeg

Gzip

gzip01.webp

web服务器处理http压缩的过程

  1. Web服务器接收到浏览器的HTTP请求后,检查浏览器是否支持HTTP压缩(Accept-Encoding 信息);
  2. 如果浏览器支持HTTP压缩,Web服务器检查请求文件的后缀名;
  3. 如果请求文件是HTML、CSS等静态文件,Web服务器到压缩缓冲目录中检查是否已经存在请求文件的最新压缩文件;
  4. 如果请求文件的压缩文件不存在,Web服务器向浏览器返回未压缩的请求文件,并在压缩缓冲目录中存放请求文件的压缩文件;
  5. 如果请求文件的最新压缩文件已经存在,则直接返回请求文件的压缩文件;
  6. 如果请求文件是动态文件,Web服务器动态压缩内容并返回浏览器,压缩内容不存放到压缩缓存目录中。
  7. 浏览器发送Http request 给Web服务器, request 中有Accept-Encoding: gzip, deflate。 (告诉服务器, 浏览器支持gzip压缩)
  8. Web服务器接到request后, 生成原始的Response, 其中有原始的Content-Type和Content-Length。
  9. Web服务器通过Gzip,来对Response进行编码, 编码后header中有Content-Type和Content-Length(压缩后的大小), 并且增加了Content-Encoding:gzip. 然后把Response发送给浏览器。
  10. 浏览器接到Response后,根据Content-Encoding:gzip来对Response 进行解码。 获取到原始response后, 然后显示出网页。

压缩的好处

http压缩对纯文本可以压缩至原内容的40%, 从而节省了60%的数据传输。

Gzip是如何压缩的

简单来说, Gzip压缩是在一个文本文件中找出类似的字符串, 并临时替换他们,使整个文件变小。这种形式的压缩对Web来说非常适合, 因为HTML和CSS文件通常包含大量的重复的字符串,例如空格,标签。

TCP/IP

TCP:是一种面向有链接的、可靠的传输层协议,它可以保证两端通信主机之间的通信可达,TCP能够正确处理在传输过程中丢包,传输顺序乱掉等异常情况。此外,tap还能够有效利用带宽,缓解网络拥堵。 为了建立和断开链接,有时他需要至少7次的发包收包,导致网络流量的浪费,此外,为了提高网络的利用效率,tcp协议中定义了,各种各样复杂的规范,因此不利于 视频 音频 的使用

TCP/IP 四层网络模型

tcp11.webp

  • 应用层:负责向用户提供应用程序,比如HTTP、FTP、Telnet、DNS、SMTP等。
  • 传输层:负责对报文进行分组和重组,并以TCP或UDP协议格式封装报文。
  • 网络层:负责路由以及把分组报文发送给目标网络或主机。
  • 链路层:负责封装和解封装IP报文,发送和接受ARP/RARP报文等。

12222.png

tcp特点:

  1. 面向连接的协议(点到点)
  2. 可靠的传输服务
  3. 全双工的通信
  4. 面向字节流的协议

封包拆包

当HTTP发起一个消息请求时,应用层、传输层、网络层和链路层的相关协议依次对该消息请求附加对应的首部,这个首部标明了协议应该如何读取数据和该层必要的信息和上层使用的协议,最终在链路层生成以太网数据包。接收方通过以太网获取数据包后,再一层一层采用对应的协议进行拆包,最后把应用层数据交给应用程序处理。简单来说,就是"发送请求时,封包,接收数据时,拆包

接收方到以太网数据包以后,再一层一层采用对应的协议进行拆包,最后把应用层数据交给应用程序处理。简单来说,就是"发送请求时,封包,接收数据时,拆包

你应该明白 TCP 连接通过什么手段来保证数据传输的可靠性,一是三次握手确认连接,二是数据包校验保证数据到达接收方,三是通过四次挥手断开连接。

tcp.jpeg

三次握手

在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。具体过程如下:

第一次握手:建立连接时,客户端发送SYN包(SYN=J)到服务器,并进入SYN_SEND状态,等待服务器确认;

第二次握手:服务器SYN包,必须确认客户的SYN(ACK=j+1),同时自己也发送一个SYN包(SYN =k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(SYN = k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

四次挥手

建立一个连接需要三次握手,而终止一个连接要经过四次握手,我们把它形象地理解为四次挥手告别。具体过程如下:

(1) 某个应用进程首先调用close,称该端执行“主动关闭”(active close)。该端的TCP于是发送一个FIN分节,表示数据发送完毕。

(2) 接收到这个FIN的对端执行 “被动关闭”(passive close),这个FIN由TCP确认。

(3) 一段时间后,接收到这个文件结束符的应用进程将调用close关闭它的套接字。这导致它的TCP也发送一个FIN。

(4) 接收这个最终FIN的原发送端TCP(即执行主动关闭的那一端)确认这个FIN。

tcp:是一种面向有链接的传输层协议,它可以保证两端通信主机之间的通信可达,TCP能够正确处理在传输过程中丢包,传输顺序乱掉等异常情况。此外,tap还能够有效利用带宽,缓解网络拥堵。 为了建立和断开链接,有时他需要至少7次的发包收包,导致网络流量的浪费,此外,为了提高网络的利用效率,tcp协议中定义了,各种各样复杂的规范,因此不利于 视频 音频 的使用

滑动窗口

我们都知道 TCP 是每发送一个数据,都要进行一次确认应答。当上一个数据包收到了应答了, 再发送下一个。这个模式就有点像我和你面对面聊天,你一句我一句。但这种方式的缺点是效率比较低的。

如果你说完一句话,我在处理其他事情,没有及时回复你,那你不是要干等着我做完其他事情后,我回复你,你才能说下一句话,很显然这不现实。 按数据包进行确认应答,所以,这样的传输方式有一个缺点:数据包的往返时间越长,通信的效率就越低。

为解决这个问题,TCP 引入了窗口这个概念。即使在往返时间较长的情况下,它也不会降低网络通信的效率。 那么有了窗口,就可以指定窗口大小,窗口大小就是指无需等待确认应答,而可以继续发送数据的最大值。

1222121.png

UDP

面向无连接的传输层协议,常用于分组数据较少或多播、广播通信及视频通信等多媒体领域

UDP区别于TCP,他是一种面向无链接的传输层协议,UDP不会关注对端是否收到了数据,如果需要检查对端是否收到了分组数据包,或者对端是否链接到了网络,则需要在应用程序中实现

UDP 特点:

  1. 物无连接协议
  2. 不可靠
  3. 面向报文传输
  4. 没有拥塞控制
  5. 首部开销非常小

UDP和TCP的区别

  • TCP面向连接(TCP发送数据之前是需要建立连接的)
  • UDP是无连接的(UDP发送数据之前是不需要建立连接的)
  • UDP传输数据速度比TCP要快一些
  • UDP是面向报文的,UDP没有拥塞控制

HTTP

HTTP 代表超文本传输协议,是几乎所有 Web 应用的基础。更具体地说,HTTP 是计算机和服务器用来请求和发送信息的方法。例如,当某人在笔记本电脑上导航至 cloudflare.com 时,其 Web 浏览器会向 Cloudflare 服务器发送 HTTP 请求,以获取页面上显示的内容。然后,Cloudflare 服务器使用浏览器显示给用户的文本、图像和格式发送 HTTP 响应。

HTTP 的第一个可用版本诞生于 1997 年。由于它经历了多个开发阶段,因此 HTTP 的第一个版本称为 HTTP1.1。此版本仍在网络上使用。2015 年诞生了一个新的 HTTP 版本,称为 HTTP2.0。

http 请求方式

  • GET: 请求指定的页面信息,并返回实体主体。
  • HEAD: 只请求页面的首部。
  • POST: 请求服务器接受所指定的文档作为对所标识的URI的新的从属实体。
  • PUT: 从客户端向服务器传送的数据取代指定的文档的内容。
  • DELETE: 请求服务器删除指定的页面。
  • OPTIONS: 允许客户端查看服务器的性能。
  • TRACE: 请求服务器在响应中的实体主体部分返回所得到的内容。
  • PATCH: 实体中包含一个表,表中说明与该URI所表示的原内容的区别。
  • MOVE: 请求服务器将指定的页面移至另一个网络地址。
  • COPY: 请求服务器将指定的页面拷贝至另一个网络地址。
  • LINK: 请求服务器建立链接关系。
  • UNLINK: 断开链接关系。
  • WRAPPED: 允许客户端发送经过封装的请求。

常见的HTTP状态码

  • **:请求收到,继续处理

  • **:操作成功收到,分析、接受

  • **:完成此请求必须进一步处理

  • **:请求包含一个错误语法或不能完成

  • **:服务器执行一个完全有效请求失败

  • 200 OK——客户端发来的请求在服务器端被正常处理

  • 204 No Content——服务器接收的请求已成功处理,但返回的响应报文中不含实体的主体部分,即无资源可返回;一般在只需从客户端往服务器发送信息,而对客户端不需要发送新信息内容的情况下使用。

  • 206 Partial Content——服务器成功执行了客户端发来的范围GET请求。

  • 301 Moved Permanently——永久重定向(请求的资源已被分配新的URL,以后应使用资源现在所指的URL)。

  • 302 Found——临时重定向(请求的资源已被分配新的URL,希望用户本次使用新的URL)。

  • 303 See Other——由于请求对应的资源存在着另一个URL,应使用GET方法定向获取请求的资源,与302功能相同,但不同点在于303要求使用GET方法获取资源。

  • 304 Not Modified——客户端发送附带条件的请求时,,服务器端允许请求访问资源,但请求未满足条件。304其实与重定向没有关系。 307 Temporary Redirect——临时重定向,但请求方式不会从POST变为GET;与302含义相同,但是302规定的禁止POST变为GET并不被遵守,而307严格遵守不会从POST变为GET

  • 400 Bad Request——请求报文中存在语法错误。

  • 401 Unauthorized——发送的请求需有通过HTTP认证的认证信息;当浏览器初次接收401,会弹出认证用的对话窗口;若之前已进行过1次请求,则表示用户认证失败。返回含有401的响应必须包含一个适用于被请求资源的WWW-Authenticate首部用以质询用户信息。

  • 403 Forbidden——对请求资源的访问被服务器拒绝了

  • 404 Not Found——服务器上无法找到请求的资源

  • 500 Internal Server Error——服务器在执行请求时发生错误

  • 503 Service Unavailable——服务器暂处于超负载或正在进行停机维护,现在无法处理请求

http1.1

  • 可以重复使用连接(keep-alive),从而节省时间,不再需要多次打开才能显示嵌入在单个原始文档中的资源

  • 添加了Pipeline,这允许在第一个请求的答案完全传输之前发送第二个请求这降低了通信的延迟

  • chunked机制,分块响应

  • 引入了额外的缓存控制机制

  • 引入了内容协商,包括语言、编码和类型,客户端和服务器现在可以就交换哪些内容达成一致

  • 由于Host标头,从同一 IP 地址托管不同域的能力允许服务器搭配

keep-alive

由于建立一个连接的过程需要DNS解析过程以及TCP的三次握手,但在同服务器获取资源不断的建立和断开链接需要消耗的资源和时间是巨大的,为了提升连接的效率。 HTTP1.1的及时出现将长连接加入了标准并作为默认实现,服务器端也按照协议保持客户端的长连接状态,一个服务端上的多个资源都可以通过这一条连接多个request来获取

HTTP1.1 中使用持久连接时,一个连接中同一时刻只能处理一个请求。当前的请求没有结束之前,其他的请求只能处于阻塞状态,这种情况被称为队头阻塞浏览器为了减轻服务器的压力,限制了同一个域名下的 HTTP 连接数,一般为 6 ~ 8 个。为了解决数量限制,出现了 域名分片 技术,其实就是资源分域,将资源放在不同域名下 (比如二级子域名下),这样就可以针对不同域名创建连接并请求,以一种讨巧的方式突破限制,但是滥用此技术也会造成很多问题,比如每个 TCP 连接本身需要经过 DNS 查询、三步握手、慢启动等,还占用额外的 CPU 和内存,对于服务器来说过多连接也容易造成网络拥挤、交通阻塞等

HTTP1.1 缺陷

  1. 高延迟,带来页面加载速度的降低,(网络延迟问题只要由于队头阻塞,导致宽带无法被充分利用)
  2. 无状态特性,带来巨大的Http头部
  3. 明文传输,不安全
  4. 不支持服务器推送消息

http2.0

HTTP2.0 解决了 HTTP1.1 的创造者未曾预料的几个问题。特别是,HTTP2.0 比 HTTP1.1 更快,更高效。HTTP2.0 速度更快的一个表现是在加载过程中如何对内容进行优先级排序。

http2.0 优点

  • 二进制帧层

  • 多路复用协议。可以通过同一连接发出并行请求,从而消除 HTTP1.x 协议的约束 3333.png

  • 头部压缩算法HPACK。由于一些请求在一组请求中通常是相似的,因此这消除了传输数据的重复和开销 22222=.png

  • 它允许服务器通过称为服务器推送的机制在客户端缓存中填充数据

HTTP2.0 和 HTTP1.1 之间还有哪些影响性能的区别?

http2.jpg

  1. 多路复用:HTTP1.1 依次加载各个资源,因此,如果无法加载某一资源,它将阻碍其后的所有其他资源。相比之下,HTTP2.0 可以使用单个 TCP 连接来一次发送多个数据流,使得任何资源都不会会阻碍其他资源。为此,HTTP2.0 将数据拆分为二进制代码消息并为这些消息编号,以便客户端知道每个二进制消息所属的流。

  2. 服务器推送:通常,服务器仅在客户端要求时才向客户端设备提供内容。但是,这种方法并不总是适用于现代网页,因为现代网页通常涉及客户端必须请求的数十个独立资源。HTTP2.0 通过允许服务器在客户端请求之前向客户端“推送”内容来解决此问题。服务器还发送一条消息,让客户知道预期推送的内容是什么,就像 Bob 在发送整本书之前向 Alice 发送小说目录一样。

  3. 标头压缩:小文件的加载速度比大文件快。为了提高 Web 性能,HTTP1.1 和 HTTP2.0 都会压缩 HTTP 消息以使其更小。但是,HTTP2.0 使用一种称为 HPACK 的更高级压缩方法,可以消除 HTTP 标头数据包中的多余信息。这样可以从每个 HTTP 数据包中消除几个字节。考虑到即使只加载一个网页时所涉及的 HTTP 数据包的数量,这些字节会迅速累加,从而加快了加载速度。