浏览器的渲染过程

117 阅读3分钟

1.解析HTML

浏览器通过网络进程获取到HTML字符串,然后渲染主进程会去解析这个字符串,也就是解析HTML,会生成DOM树和css树,也就是将字符串的形式,转化为对象形式。 Tips: 渲染主线程在解析HTML的过程中,如果遇到CSS(style、link...),渲染主线程会开辟其他的线程(预解析线程、网络线程(下载外部的css和js))来处理这些css,生成css树后,渲染主线程在处理这些css。所以说css解析不会阻塞html解析,因为它们跑在不同的线程上。 但是渲染主线程遇到js,必选暂停一切行动,要执行js。为什么js不能像css那样,是因为DOM树是边解析边生成的,不是解析完成之后才生成的,js可能会修改前面的生成的DOM树。

(1)DOM树

DOM树也就是我们标签的集合

(2)CSS树

首先会有根节点,就是代表着网页的所有样式表。 在css中包括内部样式表、外部样式表、行内样式(内联样式)表、浏览器默认样式表。 会产生四类样式表。假如有两个外部样式表,就会生成五个样式,没有此类则不生成。

2.样式计算

我们已经得到了两棵树,此时需要计算出DOM树里面的标签的样式是什么。 我们熟知的CSS属性值的计算过程:层叠(权重计算)、继承;视觉格式化模型:盒模型、包含块、浮动布局...; 都是发生在这个过程。最终每个节点都会有一个计算后的样式(computed style)

3.布局Layout

计算的元素的位置。展示结果很简单,过程很复杂。想了解过程的兄弟,就得自己去学习了,俺也不了解O(∩_∩)O哈哈~ Tips: 生成的Layout树和DOM树并不是一一对应的,出现在Layout树上的元素是能够找到集合信息的元素。display:none的元素是不会出现在layout树上的,就像head meta link标签等。像伪类元素,在DOM树中没有,但是layout树中有的

4.分层 Layer

浏览器内部会进行分层;我们可以通过will-change这个属性给浏览器提示,这个元素可能会变动频繁。

5.绘制 Paint

这里的绘制就像是一道道的指令,类似于canvas画图。 至此,渲染主线程工作结束,交给其他线程

6.分块 Tiling

将每一层分成多个块区,合成线程会启动多个线程,最大提高分块效率

7.光栅化 Raster

光栅化是什么意思呢,就是将每一个块变成位图,什么叫位图,位图其实就是每个像素点的信息了,位图其实就是内存里边,你可以把它理解为一个二维数组,里边记录了每个像素点的颜色。 光栅化的结果就是一块块的图片,此过程会用的GPU加速。

8.画 Draw

跟之前的布局不一样,布局是相对于整个页面的,那么这一块是相对于屏幕的位置在哪,该画了哪个地方先画哪个位图,再画哪个位图依次把它画出来,它根据分层结构要去计算一下,这个计算速度是很快的了,然后把这个生成的话的信息,交给GPU进程,GPU进程(属于浏览器的进程)再交给真实的硬件显卡。 tansform等就是在这一步完成的,为什么transform的效率高,是因为它不是在渲染主进程里面完成的。