# 浏览器渲染过程是怎样的

按照渲染的时间顺序,流水线可分为如下几个子阶段:构建 DOM 树样式计算布局阶段分层栅格化和显示。

渲染进程将 HTML 内容转换为能够读懂 DOM 树结构。 渲染引擎将 CSS 样式表转化为浏览器可以理解的 styleSheets,计算出 DOM 节点的样式。 创建布局树,并计算元素的布局信息。 对布局树进行分层,并生成分层树。 为每个图层生成绘制列表,并将其提交到合成线程。合成线程将图层分图块,并栅格化将图块转换成位图。 合成线程发送绘制图块命令给浏览器进程。浏览器进程根据指令生成页面,并显示到显示器上。 浏览器从网络或硬盘中获得HTML字节数据后会经过一个流程将字节解析为DOM树,先将HTML的原始字节数据转换为文件指定编码的字符,然后浏览器会根据HTML规范来将字符串转换成各种令牌标签,如html、body等。最终解析成一个树状的对象模型,就是dom树;

获取css,获取 style 标签内的css、或者内嵌的css,或者当 HTML 代码遇见标签时,浏览器会发送请求获得该标签中标记的 CSS,当渲染引擎接收到 CSS 文本时,会执行一个转换操作,将 CSS 文本转换为浏览器可以理解的styleSheets

创建布局树,遍历 DOM 树中的所有可见节点,并把这些节点加到布局中;而不可见的节点会被布局树忽略掉,如 head 标签下面的全部内容,再比如 body.p.span 这个元素,因为它的属性包含 dispaly:none,所以这个元素也没有被包进布局树。最后计算 DOM 元素的布局信息,使其都保存在布局树中。布局完成过程中,如果有 js 操作或者其他操作,对元素的** 等作出改变就会引起重绘**,如果有对元素的大小、定位等有改变则会引起**回流**。

因为页面中有很多复杂的效果,如一些复杂的 3D 变换、页面滚动,或者使用 z-index 做 z 轴排序等,为了更加方便地实现这些效果,渲染引擎还需要为特定的节点生成专用的图层,并生成一棵对应的图层树。

渲染引擎实现图层的绘制,把一个图层的绘制拆分成很多小的绘制指令然后再把这些指令按照顺序组成一个待绘制列表,当图层的绘制列表准备好之后,主线程会把该绘制列表提交给合成线程,合成线程会将图层划分为图块,然后按照视口附近的图块来优先生成位图(实际生成位图的操作是由栅格化来执行的。所谓栅格化,是指将图块转换为位图)

一旦所有图块都被光栅化,合成线程就会生成一个绘制图块的命令,然后将该命令提交给浏览器进程,浏览器最后进行显示。

# 最后

文中若有不准确或错误的地方,欢迎指出,有兴趣可以的关注下Github,一起学习呀~~

Last Updated: 2020/9/7 下午8:45:37