浏览器渲染流程

爷,独闯天下 提交于 2019-12-23 20:20:17

流水线可分为如下几个子阶段:构建 DOM 树、样式计算、布局阶段、分层、绘制、分块、光栅化和合成。

样式计算(recalculate Style)

1.将css转换为浏览器可以理解的结构

当渲染引擎接收到 CSS 文本时,会执行一个转换操作,将 CSS 文本转换为浏览器可以理解的结构——styleSheets。控制台输入:document.styleSheets即可查看

2. 转换样式表中的属性值,使其标准化

将color:blue;转化为color:rbg();将em,rem转化为px

3. 计算出 DOM 树中每个节点的具体样式

使用继承和层叠规则来算出每个节点样式

样式计算阶段的目的是为了计算出 DOM 节点中每个元素的具体样式,在计算过程中需要遵守 CSS 的继承和层叠两个规则。这个阶段最终输出的内容是每个 DOM 节点的样式,并被保存在 ComputedStyle 的结构内

布局阶段(layout)

计算出 DOM 树中可见元素的几何位置,我们把这个计算过程叫做布局。

1. 创建布局树

在显示之前,我们还要额外的创建一颗只包含可见元素的布局树。

要点总结:浏览器不能直接理解 HTML 数据,所以第一步需要将其转换为浏览器能够理解的 DOM 树结构;生成 DOM 树后,还需要根据 CSS 样式表,来计算出 DOM 树所有节点的样式;最后计算 DOM 元素的布局信息,使其都保存在布局树中。

分层

因为页面中有很多复杂的效果,如一些复杂的 3D 变换、页面滚动,或者使用 z-indexing 做 z 轴排序等,为了更加方便地实现这些效果,渲染引擎还需要为特定的节点生成专用的图层,并生成一棵对应的图层树(LayerTree);打开开发者工具中的more tools中的layers查看
在这里插入图片描述

1.拥有层叠上下文属性的元素会被提升为单独的一层。

关于层叠上下文:添加链接描述

2.需要剪裁(clip)的地方也会被创建为图层

图层绘制

一个图层的绘制拆分成很多小的绘制指令,然后再把这些指令按照顺序组成一个待绘制列表,如下图所示:
在这里插入图片描述
在这里插入图片描述

栅格化(raster)操作

绘制列表只是用来记录绘制顺序和绘制指令的列表,而实际上绘制操作是由渲染引擎中的合成线程来完成的。你可以结合下图来看下渲染主线程和合成线程之间的关系:
在这里插入图片描述
通常一个页面可能很大,但是用户只能看到其中的一部分,我们把用户可以看到的这个部分叫做视口(viewport)。为了节省开销,不会一下子绘制完所有图层,合成线程会把图层划分成一个个图块(tile),大小一般是512x512或者256X256。

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

通常栅格化过程使用GPU加速,生成的位图保存在GPU中,叫做快速栅格化。涉及跨进程操作。
在这里插入图片描述

合成和显示

一旦所有图块都被光栅化,合成线程就会生成一个绘制图块的命令——“DrawQuad”,然后将该命令提交给浏览器进程。浏览器进程里面有一个叫 viz 的组件,用来接收合成线程发过来的 DrawQuad 命令,然后根据 DrawQuad 命令,将其页面内容绘制到内存中,最后再将内存显示在屏幕上。到这里,经过这一系列的阶段,编写好的 HTML、CSS、JavaScript 等文件,经过浏览器就会显示出漂亮的页面了。

总结

在这里插入图片描述
1.将HTML内容转换为dom树。
2.样式计算,将css转化为stylesheet,使用继承和层叠规则,计算出每个节点的样式。
3.将dom树中的可见元素遍历,生成布局树,确定每个节点的位置。
4.对布局树分层,生成图层树
5.为每个图层生成绘制指令,并将其提交到合成线程。
6.合成线程将图层分为图块,在光栅化线程池中将图块转化为位图。
7.合成线程发送绘制图块命令DrawQuad给浏览器进程。
8.浏览器进程生成页面并显示到显示器上。

重绘 重排 合成

重排:重新开始布局
重绘:重新绘制
合成:前面都不动,就合成

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!