浏览器渲染流程(上)
前言
看面试题查漏补缺中,不太熟悉的点重新学习,输出文章,备战秋招。
这篇文章是讲浏览器怎么渲染出页面的。
顺带一提:本文有一些很好的过程图,是从参考文章里引用过来的,并且参考文章的图好像又是极客时间的李兵老师的视频里的。(😅)
渲染流程
解析
HTML
,生成DOM树
解析
CSS
,生成CSSOM树
布局(
Layout
)结合
DOM树
和CSSOM树
,生成渲染树
布局计算
分层(
Layer
)绘制(
Paint
)合成($\color{red}上面部分是在主线程,而合成部份是在合成线程上执行的$)
光栅化(
Raster
)合成(
Composite
)与显示
1. 生成DOM树
为什么要生成DOM
树?
因为浏览器不理解和使用HTML
,所以需要解析HTML
,转换成浏览器能够理解的结构。
上面的HTML
中获取某个节点,以及属性等都非常不方便。
生成DOM树
之后就很方便了。根节点是document
,比如我们想要访问span
标签的时候只需要document.body.children[0].firstElementChild
就可以了。如果没有生成DOM树
,那获取起来就超级复杂了,仔细想想都会觉得麻烦。
从上面的那张图,我们也可以看出来,有一个HTML解析器
的模块,将输入的HTML
解析、转换成DOM树
输出。那么它是怎么解析的呢?
通过分词器将字节流转换成
Token
。Token
分为Tag token
和文本Token
。Tag Token
又能分成Start Tag
和End Tag
。如<div>
和</div>
。将转换的
Token
列表解析为DOM节点
。可以使用栈结构来实现,遇到开始标签就入栈,遇到结束标签就出栈。(这一部分详细的知识应该是AST
抽象语法树那一块的,后续研究完再写博客)
2. 生成CSSOM树
生成CSSOM树
和生成DOM树
的目的一样,都是转换为浏览器能够理解的结构。
通过document.styleSheets
可以查看最后的结构。CSSOM
结构主要是给JavaScript提供操作样式表的能力,以及提供基础的样式信息。
上面生成DOM树
就OK了,但是这里生成CSSOM树
之后,还需要进行两步操作:
转换样式表的属性值,使其标准化
这里的转换属性,使其标准化是什么意思?
举几个例子就能够让你恍然大悟:
字体大小单位能用
px
、em
等颜色能用
red
、rgb(255, 0, 0)
等字体粗细能用
bold
、700
等
很明显,我们能根据习惯来随意选择,但是渲染引擎理解起来就很麻烦,所以需要将所有值转换为渲染引擎容易理解、标准化的计算值。
计算出
DOM
树中每个节点的具体样式计算
DOM节点
的具体样式,需要考虑CSS的继承、样式层叠规则。在上图中,灰色的就是继承的属性,而黑色则是节点新增属性,包括覆盖掉继承属性的。
注意:$\color{red}上面这颗还不是渲染树$
3. 布局(Layout)
3.1 生成渲染树
生成渲染树
的实现其实就是上两步生成的DOM树
、CSSOM树
结合起来。
注意:$\color{red}display为none的节点不会上树,而visibility为hidden的节点还是会上树。$
因为display
为none
就是指将节点从DOM树
上移出去,也就是说如果这个时候上树,之后还得把它移出去。所以就在生成渲染树
的阶段直接不让它上树。而visibility
为hidden
只是让该节点隐藏起来而已,只是看不见,其他样式都还在。
生成渲染树的示例图:
3.2 布局计算
生成渲染树
之后,需要计算渲染树
每个节点的大小和位置。
后续请看下一篇