下一个 chapter 将会介绍呈现引擎的布局/重排,在这之前稍稍把之前的知识梳理一下,以便更好地理解下一章节。
1. Rendering Engine工作的主要流程
Rendering Engine的工作流程可以总结为: Parse HTML生成DOM树 --> 生成Render树 --> Layout Render树 --> Painting
接下来按照上述几个步骤进行分别整理。
2. Parse HTML生成DOM树
所谓Parse即对输入字符串进行词法解析和语法分析后生成抽象语法树的过程。在Browser中,要parse的内容包括:HTML、CSS和Java Script。
其中,HTML由于其语法宽松不属于上下文无关语法,Parser编写比较复杂。CSS、Java Script包括XHTML的语法都属于上下文无关语法,其解析器可以用Parser Generator生成。
例如,Webkit就使用了Flex来生成词法分析器,使用Bison生成了语法分析器。其中,Flex接受的输入为定义tokens的正则表达式,Bison接受的输入为语法的BNF表示。
3. Java Script的Parse
Web标准定义了同步模型,除非有defer属性标明,否则当浏览器遇到Script的结束标志时,应当阻塞DOM树的生成,转而去解析并执行Java Script,如果
在实现中使用被称作Speculative Parsing的优化: 在执行Java Script的同时会继续DOM时的生成,但是Java Script的执行线程不会修改主DOM结构,而是委托给主线程来完成。
4. CSS的Parse
本来CSS的解析不会影响DOM树生成不应该采用同步模型,但是由于Java Script在执行时可能用到DOM元素的属性信息,所以事情又变得有些复杂:Webkit采用的策略是当Java Script访问可能被CSS影响的元素属性时Java Script解析执行线程会Block,而Gecko则会等所有CSS都载入完成后再开始Java Script的解析执行。
5. Rendering树的生成
每当DOM树发生改变时都需要更新对应的Rendering树。Rendering树用树的结构组织页面中的可视元素,每个节点对应一个页面中的矩形可视元素,根节点对应浏览器窗口的可视区域。
Rendering树中的元素与DOM树中的元素有较强的对应关系,主要的不匹配情况包括以下三种:
设置为display:none的元素不会出现在Rendering树中。
有的DOM元素会对应多个Rendering树元素,如一个Select对应三个Rendering树元素,一个是未展开时的显示内容,一个按钮,和一个展开时显示内容。
有些Rendering树节点与DOM树节点对应,但在树中的位置不同,如display:float和display:absolute的元素,这些元素在Rendering树中被单独放置,但在原DOM树中的位置会放一个Placeholder节点。
6. 布局与Layout
将会在下一章节介绍。
就这么总结一下。