《浏览器工作原理与实践》渲染流程笔记

173 阅读3分钟

所谓渲染过程就是将HTML、CSS、JavaScript转变成页面的过程~

渲染过程大致如下:

构建DOM树 》 样式计算 》 布局阶段 》 分层 》 绘制 》 分块 》 光栅化 》 合成

一、构建DOM树

将HTML转化成DOM的过程就是构建DOM树。

DOM树是存储在内存中的,便于JavaScript直接查询和修改。

二、样式计算

目的是:计算出每个DOM节点的样式,如下图所示,结果保存在computedStyle中

企业微信截图_16487803606741.png

具体过程如下:

(1)将css转成styleSheets

目的是方便查询和修改,为样式操作提供基础~

(2)对styleSheets的样式标准化

所谓标准化就是将类似rem转成px、color转成rgb格式等

(3)计算每个DOM节点的样式,输出并保存在computedStyle中

如何计算DOM节点的样式呢?就牵扯到样式的继承规则和层叠规则

三、布局阶段

所谓布局就是计算DOM树的可见DOM节点(不包括display:none的元素、header元素)位置的过程~分为两个过程。

(1)将DOM树和computedStyle重新生成布局树(只包含可见元素),布局树的每个DOM节点都包含计算之后的样式

(2)布局计算

计算布局树节点的坐标位置~计算完成之后会把结果重新写会布局树中,所以此时布局树是包含DOM节点、computedStyle和坐标位置的结构

四、分层

渲染引擎会为特定的节点(3D转换、页面滚动、z-index、position等)生成专用的图层;

浏览器的页面实际上被分成很多图层,图层的叠加后就合成页面

哪些元素会生成图层呢?

(1)拥有层叠上下文属性(z-index、明确定位属性、拥有opacity、css滤镜filter等)的元素会被提升为图层

(2)、需要剪切clip和有滚动条的也会创建图层

最后生成图层树~

五、图层绘制

完成图层树的构建之后,渲染引擎会对图层树的每个图层进行单独绘制

渲染引擎如何绘制图层的呢? 渲染引擎实现图层的绘制会把图层的绘制拆分成很多小的绘制指令 ,在按照指令顺序组成绘制列表,就像我们们绘画的步骤一样,要按照步骤一步步完成~

六、栅格化

图层绘制输出的是绘制列表,记录了绘制顺序和绘制指令的列表,但是实际的绘制是又渲染引擎中的合成线程完成的。 当图层的绘制列表准备好之后,主线程会把该绘制列表提交(commit)给合成线程

合成线程是如何完成绘制的呢?

(1) 视口(当前可见部分)

确实没必要把页面所有的部分都绘制出来,浪费性能~ 所以合成线程会将图层划分为图快,图快的大小通常是256256或者512512;

合成线程会按照视口附近的图块来优先生成位图,实际生成位图的操作是由栅格化来执行的。所谓栅格化,是指将图块转换为位图。

栅格化一般会通过GPU加速生成,使用GPU生成位图的过程叫做快速栅格化或者GPU栅格化,生成的位图保存在GPU内存中~ 渲染进程把生成图块的指令发送给 GPU,然后在 GPU 中执行生成图块的位图,并保存在 GPU 的内存中。

这个阶段输出的是位图~

七 合成与显示

一旦图块光栅化之后,合成线程就会生成绘制图块的命令(DrawQuad),提交给浏览器进程

浏览器进程的viz组件,接收到合成线程发来的DrawQuad命令后,根据命令,将页面内容绘制到内存中,最后显示在屏幕上。