前言
面试官:用户通过在地址栏输入一个 URL,最终渲染完成,背后发生了什么?
我:......
导航
DNS查询
当你通过在地址栏输入一个 URL、点击一个链接、提交表单或者是其他的行为。 浏览器就需要根据输入去查询要访问的资源,域名需要通过域名服务器(DNS)查询域名所对应的ip地址并返回终端,才能做后续的资源访问
注意:页面域名只需要查询一次,但页面内部访问的资源例如:图片,视频,字体等,会造成多次查询DNS,如果次数较多会导致加载缓慢,多次 DNS 查询需要消耗更多的网络带宽和处理器时间,导致页面加载速度变慢。
响应
当我们通过导航得到服务器ip,浏览器就会向服务器发送请求,一般来说是返回一个HTML文件,这个过程中浏览器会多次请求服务器获取页面加载需要的资源,内容分块数据包返回给客户端。这个过程如下
[拥塞控制 / TCP 慢启动]
TCP 数据包在传输过程中被分成若干段。由于 TCP 保证数据包的顺序,因此服务器在发送一定数量的数据包后,必须以 ACK 数据包的形式收到客户端的确认。
如果服务器在每个网段后都等待 ACK,则会导致客户端频繁发出 ACK,即使在网络负荷较低的情况下也会增加传输时间。
另一方面,一次性发送过多网段可能会导致这样的问题:在繁忙的网络中,客户端无法接收到网段,只能长时间不停地回应 ACK,服务器不得不不断重新发送网段。
为了平衡传输段的数量,TCP算法用于逐渐增加传输数据量,直到确定最大网络带宽,并在网络负载较高时减少传输数据量。
传输段的数量由拥塞窗口(CWND)的值控制,该值可初始化为 1、2、4 或 10 MSS(以太网协议中的 MSS 为 1500 字节)。该值是发送的字节数,客户端收到后必须发送 ACK。
如果收到 ACK,那么 CWND 值将加倍,这样服务器下次就能发送更多的数据段。相反,如果没有收到 ACK,那么 CWND 值将减半。因此,这种机制在发送过多网段和过少网段之间取得了平衡。
解析
解析也可以看成是将收到的数据整理成浏览器绘制成页面的基本框架。
DOM 树
第一步处理DOM,其实就是我们接收到的html也是我们在js中使用的DOM,通过html元素构建文档树构成页面的基本骨架。
构建的时间取决于DOM节点的多少,所以如果想减少构建时间,尽量减少DOM节点的数量;并且解析过程也会受到非异步<script>标签的影响;
解析 DOM完成后会触发DOMContentLoaded事件,它有区别于load事件,前者是DOM元素资源加载完成后触发,后者是所有资源触发
CSSOM 树
第二步是处理 CSS 并构建 CSSOM 树。CSS 对象模型和 DOM 是相似的。DOM 和 CSSOM 是两棵树。它们是独立的数据结构。浏览器将 CSS 规则转换为可以理解和使用的样式映射。浏览器遍历 CSS 中的每个规则集,根据 CSS 选择器创建具有父、子和兄弟关系的节点树。
与 HTML 一样,浏览器需要将接收到的 CSS 规则转换为可以使用的内容。因此,它重复了 HTML 到对象的过程,但对于 CSS。
CSSOM 树包括来自用户代理样式表的样式。浏览器从适用于节点的最通用规则开始,并通过应用更具体的规则递归地优化计算的样式。换句话说,它级联属性值。
构建 CSSOM 非常快,并且在当前的开发工具中没有以独特的颜色显示。相反,开发人员工具中的“重新计算样式”显示解析 CSS、构建 CSSOM 树和递归计算计算样式所需的总时间。在 web 性能优化方面,它是可轻易实现的,因为创建 CSSOM 的总时间通常小于一次 DNS 查询所需的时间。
渲染
第三步渲染就是将DOM和CSSOM合成并最终绘制到屏幕上的一个过程。
渲染分为三步;
1.将 DOM 和 CSSOM 合并为渲染树(redding tree)
计算样式规则,css计算过程,然后生成渲染树。
2.渲染树的每个元素的内容都是计算过的,称之为 布局(layout)
计算元素的位置和尺寸。
重排:页面交互中布局会被改变,这就会导致重排
3.将渲染树上的各个节点绘制到屏幕上,称之为 绘制(painting)
重绘:页面一直都在不断重绘,它靠GPU完成,绘制比重排效率更高,重排一定会重绘