输入URL到页面渲染的整个流程

1)应用层进行DNS解析

通过域名解析成IP地址。在解析过程中,按照浏览器缓存系统缓存路由器缓存ISP(运营商)DNS缓存根域名服务器顶级域名服务器主域名服务器的顺序,逐步读取缓存,直到拿到IP地址。

DNS协议是一个查询/回复的协议,查询和回复的数据格式相同。当一个应用需要把域名解析为一个IP地址时,就调用解析程序,称为DNS的一个客户,把待查询的域名以UDP数据报的方式发给本地域名服务器。本地域名服务器查询缓存,如果存在则把对应的IP地址放在回答报文中返回。应用程序获得目的主机的IP地址后即可进行通信。

递归与迭代的区别

如果本地DNS服务器本地区域文件与缓存解析都失效,则根据本地DNS服务器的设置(是否设置转发器)进行查询,如果未用转发模式,本地DNS就把请求发至 “根DNS服务器”,“根DNS服务器”收到请求后会判断这个域名(.com)是谁来授权管理,并会返回一个负责该顶级域名服务器的一个IP本地DNS服务器收到IP信息后,将会联系负责.com域的这台服务器。这台负责.com域的服务器收到请求后,如果自己无法解析,它就会找一个管理.com域的下一级DNS服务器地址(qq.com)给本地DNS服务器。当本地DNS服务器收到这个地址后,就会找qq.com域服务器,重复上面的动作,进行查询,直至找到www.qq.com主机。

如果用的是转发模式,此DNS服务器就会把请求转发至上一级DNS服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根DNS或把转请求转至上上级,以此循环。不管是本地DNS服务器用是是转发,还是根提示,最后都是把结果返回给本地DNS服务器,由此DNS服务器再返回给客户机。

 

递归是用户只向本地DNS服务器发出请求,然后等待肯定或否定答案。而迭代是本地服务器向根DNS服务器发出请求,而根DNS服务器只是给出下一级DNS服务器的地址,然后本地DNS服务器再向下一级DNS发送查询请求直至得到最终答案。

 

这里可以使用预解析,提前解析可能用到的域名,使解析结果缓存到系统缓存中,缩短DNS解析时间,提高网站访问速度。

2)应用层生成HTTP请求报文

HTTP请求报文包括起始行、首部和主体部分。

如果访问的google.com,则起始行可能如下

GET https://www.google.com/ HTTP/1.1

首部包括域名host、keep-alive、User-Agent、Accept-Encoding、Accept-Language、Cookie等信息

首部和主体内容之间有一个回车换行(CRLF),主体内容即要传输的内容。如果是get请求,则主体内容为空

3)传输层建立TCP连接

TCP协议是面向连接的,所以它在开始传输数据之前需要先建立连接。要建立或初始化一个连接,两端主机必须同步双方的初始序号。同步是通过交换连接建立数据分段和初始序号来完成的,在连接建立数据分段中包含一个SYN(同步)的控制位。同步需要双方都发送自己的初始序号,并且发送确认的ACK。此过程就是三次握手

TCP三次握手我之前有写过随笔,就不再介绍。

构建TCP请求会增加大量的网络时延,常用的优化方式如下所示

(1)资源打包,合并请求

(2)多使用缓存,减少网络传输

(3)使用keep-alive建立持久连接

(4)使用多个域名,增加浏览器的资源并发加载数,或者使用HTTP2的管道化连接的多路复用技术

4)网络层使用IP协议来选择路线

处理来自传输层的数据段segment,将数据段segment装入数据包packet,填充包头,主要就是添加源和目的IP地址,然后发送数据。在数据传输的过程中,IP协议负责选择传送的路线,称为路由功能

5)数据链路层实现网络相邻结点可靠的数据通信

为了保证数据的可靠传输,把数据包packet封装成帧(Frame),并按顺序传送各帧。由于物理线路的不可靠,发出的数据帧有可能在线路上出错或丢失,于是为每个数据分块计算出CRC(循环冗余检验),并把CRC添加到帧中,这样接收方就可以通过重新计算CRC来判断数据接收的正确性。一旦出错就重传。

6)物理层传输数据

数据链路层的帧(Frame)转换成二进制形式的比特(Bit)流,从网卡发送出去,再把比特转换成电子、光学或微波信号在网络中传输

7)服务器传输一个HTTP响应报文

8)浏览器解析

1、如果HTTP响应报文是301或302重定向,则浏览器会相应头中的location再次发送请求

2、浏览器处理HTTP响应报文中的主体内容,首先使用loader模块加载相应的资源

3、使用parse模块解析HTML、CSS、Javascript资源 

9)浏览器渲染

 

指一系列在首屏渲染中必须发生的事件

获取html > 获取资源 > 解析 > 显示页面

某些资源(css/js)加载会阻塞页面渲染;这些非必须资源花费大量时间加载,应考虑移出关键路径。

首屏渲染需要关注三件事:优化资源数量/优化子节数/优化路径长度

  • 图片懒加载:一开始只加载首页的图片
  • js文件:只加载首屏的js
  • 减少css文件,或者合并外部css文件,或者内嵌css

 

(构建渲染树)

  • 从DOM树的根节点开始遍历每个可视节点。
  • 对每个这样的节点,找到CSSOM树中对应的规则,并应用他们。
  • 根据每个可见节点及其对应样式,生成渲染树。

3. 回流:根据渲染树,得到节点的位置和大小;

4. 重绘:根据渲染树以及回流,得到节点的绝对像素;

5. 将像素发送给GPU,展示在页面上。

 

重绘:通过构造渲染树和回流阶段后,将每个节点转换成屏幕上的实际像素;

回流:计算渲染树节点在设备视图内的确切位置和大小,那么当页面布局和几何信息发生变化时就需要回流。比如:

  • 添加或删除可见的DOM元素
  • 元素的位置发生变化
  • 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
  • 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代。
  • 页面一开始渲染的时候(这肯定避免不了)
  • 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)

回流必定会发生重绘,重绘不一定会引发回流。

1)现代的浏览器都是很聪明的,由于每次重排都会造成额外的计算消耗,因此大多数浏览器都会通过队列化修改并批量执行来优化重排过程。浏览器会将修改操作放入到队列里,直到过了一段时间或者操作达到了一个阈值,才清空队列。但是!当你获取布局信息的操作的时候,会强制队列刷新,比如

  • offsetTop、offsetLeft、offsetWidth、offsetHeight
  • scrollTop、scrollLeft、scrollWidth、scrollHeight
  • clientTop、clientLeft、clientWidth、clientHeight
  • getComputedStyle()
  • getBoundingClientRect

所以最好避免以上属性,如要使用,最好将值缓存起来。

 

2)批量修改DOM,先使元素脱离文档流

隐藏元素,应用修改,重新显示

使用文档片段在外构建子树,再拷贝回当前DOM

将原始元素拷贝到一个脱离文档的节点中,修改节点后,再替换原始的元素

 

3)对于复杂动画效果,使用绝对定位让其脱离文档流

4)使用css3硬件加速,可以让transform、opacity、filters这些动画不会引起回流重绘 。

如果你为太多元素使用css3硬件加速,会导致内存占用较大,会有性能问题。

 

原文链接:https://www.cnblogs.com/lora404/p/12488032.html

原创文章,作者:优速盾-小U,如若转载,请注明出处:https://www.cdnb.net/bbs/archives/16451

(0)
上一篇 2022年11月16日 22:26
下一篇 2022年11月16日

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

优速盾注册领取大礼包www.cdnb.net
/sitemap.xml