CDN缓存DNSTCP三向握手、四向握手浏览器渲染过程输入URL到页面渲染过程中的一些优化下面我就粗略的描述一下“从输入URL到渲染的全过程”,然后再解释过程,了解流程中可以进行哪些优化。文章内容有点长,需要有足够的耐心看完!!现在我要开始了!1.URL解析2.DNS解析3.建立TCP连接4.客户端发送请求5.服务器处理并响应请求6.浏览器解析并渲染响应内容7.TCP四次挥手断开连接1.URL解析地址解析及编码我们输入网址后,浏览器会对输入的字符串进行解析,判断它是网址还是搜索关键词,如果是网址,就会开始编码。一般来说,网址只能使用英文字母、阿拉伯数字和一定的标点符号,不能使用其他文字和符号。因此,如果URL中有文本,则必须对其进行编码并使用。但是,URL编码非常混乱。不同的操作系统、浏览器和网页字符集会导致不同的编码结果。所以我们需要先用JavaScript对URL进行编码,然后在不给浏览器干预机会的情况下提交给服务器。我们通常使用encodeURI()函数或encodeURIComponent()函数对URL进行编码HSTSHSTS(HTTPStrictTransportSecurity)是一种新的网络安全协议。HSTS的作用是强制客户端使用HTTPS与服务器建立连接。比如在地址栏输入http://xxx/,浏览器会自动将http转录成https,然后直接向https://xxx/发送请求。缓存检查浏览器在发送请求前检查是否有缓存。流程如下:浏览器会先检查强缓存(Expires和cache-control),判断是否过期。如果强缓存生效,则直接从缓存中读取资源;如果不生效,则执行协商缓存(Last-Modified/If-Modified-Since和Etag/If-None-Match)。服务器决定是否使用缓存。如果协商缓存失败,则说明该请求的缓存失效,返回200,并返回资源和缓存ID,重新存入浏览器缓存;如果生效,返回304,从缓存中读取资源。(在协商缓存之前需要先进行DNS域名解析,然后建立TCP连接)那么浏览器缓存在哪里呢?ServiceWorker:浏览器独立线程,用于缓存MemoryCache:内存缓存DiskCache:硬盘缓存PushCache:推送缓存(在HTTP/2中)注意:输入URL后,会搜索内存缓存。发生网络请求。普通刷新(F5):因为TAB没有关闭,内存缓存可用。如果匹配则优先使用,然后强制刷新磁盘缓存(Ctrl+F5):浏览器不使用缓存,所以发送的请求头都是带Cache-control:no-cache的,服务器直接返回200和最新的内容。更多面试题解答请参考前端高级面试题详细解答。2、进行DNS解析DNS(1)、DNS:一种分布式数据库,将域名和ip地址相互映射,让用户更方便地访问互联网。DNS协议运行在UDP协议(2)之上,DNS解析:通过域名最终得到对应ip地址的过程。(3)DNS缓存:浏览器??、操作系统、路由器、本地DNS、根域名服务器都会对DNS结果进行一定程度的缓存。DNS解析过程(1),首先查找浏览器自身的DNS缓存,有缓存则直接返回;(2)如果浏览器自带的DNS不存在,浏览器会调用一个类似gethostbyname的库函数。这个函数会先查看本地的hosts文件,看是否有对应的ip。(3)如果本地hosts文件中没有映射关系,则查询路由缓存。如果路由缓存不存在,则查找本地DNS服务器(一般会在TCP/IP参数中设置首选DNS服务器,一般为8.8.8.8)(客户端到本地的DNS服务器是递归的process)(4)、如果没有找到本地DNS服务器,就会向根服务器发送请求。(DNS服务器是一个迭代的过程)具体过程:本地DNS服务器代表我们的浏览器发起一个迭代的DNS解析请求。首先,它会找到根域的DNSIP地址(全球13个,可惜中国没有!)。当找到根域的DNS地址时,就会向它发起请求(域名www.baidu.com的IP地址是多少?);根域发现这是一个顶级域com域的域名,于是告诉本地DNS服务器我不知道这个域名的IP地址,但是我知道com域的IP地址,你可以去找它;于是本地DNS服务器获取到com域的IP地址,向com域的IP地址发起请求(请问域名www.baidu.com的IP地址是多少?),于是com域服务器告诉本地DNS服务器,我不知道域名www.baidu.com的IP地址,但是我知道域名baidu.com的DNS地址,你去找吧;然后本地DNS服务器向域名baidu.com的DNS地址发起请求(这个一般由域名注册商提供,比如万网,新网等)(请问域名www.baidu.com域的IP地址是多少?),这时候查看baidu.com域的DNS服务器,啊!如果真的在这里,我把查到的结果发给本地的DNS服务器;此时本地DNS服务器获取到域名www.baidu.com对应的IP地址。DNS优化DNS也是一种开销,通常浏览器需要20-120毫秒来查找给定域名的IP地址,并且在域名解析完成之前浏览器无法从服务器加载任何内容。那么如何减少域名解析时间,加快页面加载速度呢?(1)、减少DNS请求次数(2)、DNS预获取,DOM还没有启动,浏览器预解析地址,将解析后的地址放入本地缓存。DOM树生成后,需要加载图片类,找到DNS解析过的,然后发送请求。(主要针对图片资源)(3)、DNS查询的过程经过了很多步骤,如果每次都出现这种情况,就会花费更多的时间和资源。所以我们应该尽快返回真实的IP地址:(减少查询过程,也就是DNS缓存。浏览器获取到IP地址后,一般会缓存在浏览器缓存中,本地DNS缓存服务器可以也记录下。另外,域名服务器如何满足每天上亿网名,每秒上千万请求的访问需求呢?就是DNS负载均衡。通常我们的网站使用各种云服务,或者各种服务提供商提供类似的服务,他们去帮助我们处理这些问题。DNS系统根据每台机器的负载、地理位置限制(远距离传输效率)等,提供高效、快速的DNS解析服务。(4)当客户端DNS缓存(浏览器和操作系统)缓存为空时,DNS查找的数量与要加载的网页中唯一主机名的数量相同,包括页面URL、脚本、样式表、图片、Flash对象的主机名等。减少主机名的数量可以减少DNS查询次数;(5)、减少唯一主机名的数量可以潜在地减少页面中并行下载的数量(HTTP1.1规范建议从每个主机名并行下载两个组件,但实际上可以有多个);但是减少主机名和并行下载的方案会产生矛盾,大家需要做出取舍。建议将组件放在至少两个但不超过4个主机名下,以减少DNS查找,同时允许高度并行下载。DNS解析后,域名的解析权将交给cname()指向的内容分发(CDN)专用DNS服务器。CDN专用的DNS服务器将CDN的全局负载均衡设备的IP地址返回给用户。CDN举个例子:以前买火车票,得去火车站买票。大家去火车站买票。火车站售票处的压力可想而知。后来出现了火车票销售网点,分布在各个城镇。我们只需到就近的火车票销售点购票即可。销售火车票的代理售票处(缓存服务器)为购票者提供便利,帮助购票(获取资源)。降低了售票大厅的压力(起到分流的作用,减轻服务器负载压力)CDN缓存:浏览器??本地缓存失效后,浏览器会像CDN边缘节点一样发起请求,类似于浏览器缓存,也有一个设置CDN边缘节点缓存机制,CDN边缘节点缓存策略因服务提供商而异,通过http响应头中的cache-control:max-age字段设置CDN边缘节点数据缓存时间。当浏览器向CDN节点请求数据时,CDN节点会判断缓存的数据是否过期。如果缓存数据过期,CDN会向服务端发送回源请求,从服务端拉取最新数据,更新本地缓存,返回最新数据给客户端,CDN服务商一般提供多维度的基础在文件后缀和目录上指定CDN缓存时间,为用户提供更精细的缓存管理。CDN工作方式:(1)当你点击网站页面的url时,经过DNS解析后,域名的解析权将交给cname()指向的内容分发专用DNS服务器。内容分发专用DNS服务器返回内容分发的GSLB设备的IP地址给用户。(2)当你向CDN全局负载均衡器的ip地址发起url访问请求时,CDN全局负载均衡器会选择合适的缓存服务器为你提供服务。选择的依据:用户的ip地址,判断哪个服务器距离用户最近,根据用户请求的url中携带的内容名称,判断哪个服务器有用户想要的数据,查询各个服务器当前的负载情况,并确定哪个服务器具有服务功能。赋值:根据这些条件综合分析后,区域负载均衡设备请求全局负载均衡设备返回一个缓存服务器的IP地址。全局负载均衡设备返回服务器的IP地址,用户向缓存服务器发起请求,缓存服务器响应用户请求,将用户需要的内容传送给用户终端。如果缓存服务器没有用户想要的内容,区域平衡器仍然会分配给用户,然后这台服务器会向它的上级缓存服务器请求内容,直到追溯网站的源服务器将内容拉到本地。域名解析服务器根据用户的ip地址将域名解析成对应节点的缓存服务器ip地址,实现用户就近访问。对于使用CDN服务的网站,只要将域名解析权交给CDN的全局负载均衡器,就需要分发内容加速,可以通过向CDN注入内容来实现。CDN的优势:(1)、CDN节点解决了跨运营商、跨地域访问的问题,访问时延大大降低;(2)、大部分请求在CDN的边缘节点完成,CDN起到导流作用,减轻源服务器负载。CDN的缺点(一)。网站更新时,如果CDN节点上的数据没有及时更新,即使用户在浏览器中使用Ctrl+F5使浏览器端的缓存失效,也会导致CDN边缘节点没有更新同步最新数据。用户访问异常。(2)CDN的缓存时间不同会直接影响“回源率”:如果缓存时间短,CDN边缘节点的内容会经常失效,导致频繁回源.不仅增加了服务器压力,还增加了用户访问时间。如果缓存时间长,数据有更新,而边缘节点的内容还没有更新,开发者会针对具体的任务管理具体的数据缓存时间。CDN刷新缓存CDN边缘节点对开发者是透明的。相对于浏览器强制刷新Ctrl+F5使浏览器本地缓存失效,开发者可以使用CDN服务商提供的“刷新缓存”接口来达到清理CDN边缘节点缓存的目的。这样,开发者在更新数据后,可以通过“刷新缓存”功能强制CDN节点上的数据缓存过期,保证客户端访问时拉取到最新的数据。|CDN优化(一)、需要加速的前端文件一般包括:js、css、图片、视频、页面。有动态和静态页面文件。这些文件和页面(比如html)最大的区别就是这些文件是静态的,变化比较小。这样的静态文件适合CDN加速。我们通过CDN把这些静态文件分发到世界各地的节点,用户可以在最近的边缘节点获取到他们需要的内容,从而提高内容的下载速度,加快网页的打开速度。页面分为动态页面和静态页面。动态页面不适合CDN缓存,因为如果页面是动态的,内容的有效期比较活跃。边缘节点的数据经常出现故障,需要回源,给源服务器造成压力。(2)减少资源请求的等待时间。不同的浏览器有不同的并发连接数:IE11、IE10、chrome、Firefox有6个并发连接数,IE9有10个连接数。如果页面上的静态资源(图片等)过多(超过6个),资源请求就会等待。现在的现实是大部分用户的带宽越来越大,但是我们的静态资源却没有那么大。很多文件是几k或几十k,6个文件加起来还不到带宽。这会导致资源浪费。解决办法是:使用多台不同IP的服务器来存放这些文件,在页面中通过绝对路径的方式引用(同一IP的文件不超过6个)。这样可以尽可能减少资源请求等待的情况。至此,您已经获取到缓存服务器的IP地址,可以向该IP地址发送请求了。3、建立TCP连接TCP(1)、TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。(2)建立一个TCP连接,需要三次握手。过程如下:TCP握手过程(1),客户端发送一个带有SYN标志(SYN=1,seq=x)的请求报文,然后进入SYN_SEND状态,等待服务器确认;(2)、服务器收到客户端SYN报文段后,需要发送ACK信息来确认SYN,同时发送自己的SYN信息(SYN=1,ACK=1,seq=y,ack=x+1).服务端将这些信息放在一个报文段((SYN+ACK报文段)中,一起发送给客户端。此时,客户端进入SYN_RECV状态;(3).收到SYN+ACK报文段后从服务端,客户端发送服务端发送ACK(ACK=1,seq=x+,ack=y+1)确认报文段,报文段发送完成后,客户端和服务端都进入ESTABLISHED状态,并且完成三次握手。为什么TCP一定要建立三次呢?做两次可以吗?原因:双方都需要确定对方的接收能力是正常的。(客户端发送后,服务端可以确认客户端发送能力正常接收发送能力正常,最后客户端发送确认,判断客户端接收能力。为了防止无效的连接请求报文段被发送到服务端突然,导致错误。4.client发送TCP三次握手请求连接成功后,client开始按照指定的格式向server发送HTTP请求。请求流程优化,减少HTTP请求次数和请求资源大小(一),资源合并压缩(二),字体图标(精灵基本不行,优化方式不易维护)(三)、base64(4)、Gzip(一般文件可以压缩60%)(5)、图片延迟加载(6)、数据延迟批量加载(7)、CDN资源5、服务端响应请求。服务器收到请求后,web服务器(准确的说应该是http服务器)处理请求,如Apache、Ngnix、IIS等。web服务器解析用户请求,了解要调度哪些资源文件,然后通过响应资源文件处理用户请求和参数,调用数据库信息,最后通过web服务器将结果返回给浏览器客户端。6、Disconnect服务器响应客户端的请求后,释放TCP连接。释放过程(挥手四次)如下:(1)。客户端发送标记为FIN=1(finished的缩写,表示接收完成,释放请求)连接),同时生成一个Seq=u的序号,然后进入FIN-WAIT-1半关闭阶段(此时客户端向服务端发送数据的通道已经关闭,但仍然可以接收到服务端发送的数据);(2)服务器收到连接释放报文,发送确认报文,ACK=1,ack=u+1,并带上自己的序号seq=v,此时服务器进入CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层应用进程,客户端向服务器方向释放。此时处于半关闭状态,即客户端没有数据发送,但是如果服务端发送数据,客户端还是要接受。这个状态会持续一段时间,也就是整个CLOSE-WAIT状态的持续时间。(3)客户端收到服务器的确认请求后,此时,客户端进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放消息(在此之前,需要接受服务器发送的最后一条消息)。数据)。(4)服务器发送完最后一个数据后,向客户端发送连接释放消息,FIN=1,ack=u+1,因为处于半关闭状态,服务器可能又发送了一些数据,假设此时服务器的序号为seq=w。此时服务器进入LAST-ACK(最终确认)状态,等待客户端的确认。(5)客户端收到服务器的连接释放报文后,必须发送确认,ACK=1,ack=w+1,自己的序号为seq=u+1。此时客户端进入TIME-WAIT(等待时间)状态。(6)服务器只要收到客户端的确认,就立即进入CLOSED状态,结束本次TCP连接。为什么我们需要握手四次而不是三次两次?因为一旦建立连接,双方既是发送者又是接收者。以保证在最终断开连接时,客户端发送的最后一个ACK报文段能够被服务器接收到。如果客户端在收到服务器的断开连接请求后直接断开连接,服务器会因为没有收到客户端的响应而等待,所以客户端要等待两个最长生命周期的消息段,这样服务器可以在没有收到请求后重新发送请求。7、浏览器解析并渲染响应内容。在此之前,先补充一些基础知识:浏览器渲染引擎的组成(列出基本组件)(1)、HTML解析器:将HTML解析成DOM树。(2)、CSS解析器:计算DOM中每个元素对象的样式信息,为布局提供基础设施。(3)、JavaScript引擎:解析并执行javascript代码。(4)布局模块:DOM树创建完成后,webkit需要结合其中的元素对象和样式信息,计算出它们的大小和位置等布局信息,形成一个能够表达所有信息的模型。(5)绘图模块:利用图形库将布局计算后的各个网页的节点绘制成图像。渲染过程(1),浏览器拿到文件后(拿到一些字节码),通过编码(通常是utf-8)转换成相应的字符。(2)浏览器从上到下解析文档。当它遇到HTML标签时,它会调用HTML解析器将其解析为相应的标记。令牌是标记文本的序列号。根据词法分析将token解析成特定的标签结构。这个过程已经构建生成了一个DOM树,有标签,有层,有结构(也就是一块内存,其实是由Tocken组成的);(3)、遇到style/link标签,调用CSS解析器处理CSS标签,构建CSSOM样式树;(4)、遇到script标签,调用javascript解析器进行处理,绑定事件,修改DOM树/CSS树等;(5)、将DOM树和CSSOM树合并为一棵渲染树(rendertree)。(6)根据渲染树进行渲染,计算出每个节点的几何信息(这个过程依赖于图形库);(7)将每个节点绘制到屏幕上。如果用户操作页面,会触发步骤(6)或(7),即重排重绘阻塞渲染(1)、style标签的样式:由HTML解析器解析(异步解析);不阻塞浏览器Rendering(可能会出现闪屏(解析一点,显示一点现象);不阻塞DOM解析。(2)、链接引入的外部css样式(推荐)由CSS解析parser(同步解析);阻塞浏览器渲染(这种阻塞可以用来避免splashscreen);阻塞后续js语句的执行:原因:如果后续js的内容是获取元素的样式,比如宽高等属性,如果样式没有解析出来,后面的js会报错由于浏览器并不知道后面js的具体内容,所以要等前面的样式全部解析完才可以执行js。例如:firefox在样式加载和解析过程中会禁止所有脚本。(具有webkit内核的浏览器只会在js尝试访问样式属性或者可能受卸载样式影响时禁止脚本。不阻塞DOM解析:原因:DOM解析和CSS解析是两个并行线程。(3)、优化内核概念:尽可能快地提高外部css的加载速度。利用CDN节点打包外部资源;压缩css(使用打包工具,如webpack、glup等;减少http请求次数,多个css文件合并;优化样式代码。(4)、jsblocking:blockingDOMparsing:原因:浏览器不知道后续脚本的内容,如果先解析后面的DOM,然后js把后面的DOM全部删除,就完了无用功,浏览器无法预测脚本的作用,索性暂停所有脚本,脚本执行完毕,浏览器继续往下解析。阻塞页面的渲染:原因:js还可以为DOM,和浏览器做的一样Waituntil在继续工作之前先执行脚本,避免无用功。阻塞后续js的执行:原因:维护依赖,例如:必须先引入jQuery,再引入bootstrap。如果script脚本加了defer:浏览器会发出加载js的请求,但不会阻塞DOM解析,等DOM解析完成后再执行js。如果脚本加了async:浏览器会发送请求加载js,不会阻塞DOM解析。当js加载完成后,会先停止DOM解析,执行js(谁先回来先执行),等待js执行完毕,继续DOM解析。渲染过程优化(1),标签语义(使用合适的标签,如果不是w3c规定的标签,Tockentoken和词法分析语法一定要识别分析,是wc3规定的吗)(2),减少标签嵌套(也是生成的结构树嵌套多,需要递归(在构建DOM树时可以更快)(3)、尽可能少的样式嵌套(与编译器一起使用时,应谨慎使用分层嵌套。CSS选择器是从右向左渲染的,.boxa{}会比a{}慢(4)、尽快将CSS下载到客户端(充分利用HTTP多请求并发机制)(5)避免阻塞底层js(6),减少回流,摒弃传统操作DOM时代,开启数据影响基于vue/reacttry模式风格集中改变缓存布局信息,对position属性为absolute或fixed的元素应用动画效果(出文档流)CSS3硬件加速(相比考虑如何减少回流重绘,希望不回流重绘:transform、opacity、filters等属性会触发硬件加速,不会造成回流重绘(过度使用需要占用内存大,性能消耗严重避免使用表格布局,使用cssjs表达式结论看了这篇文章,相信小伙伴们对流程有了一个大概的了解输入URL以呈现页面。事实上,整个过程非常复杂和繁琐。它不仅仅是一篇文章或几张图片。可以包括在内,还有很多细节不便在这里展开。有兴趣的朋友可以深入研究这个过程的一些细节!文中肯定会有一些不是很清楚的地方,还望大家赐教。一起成长!