衔接

接着上文继续。

在构建好render树后,浏览器就开始进行布局了。这意味着浏览器会给每个节点正确的坐标,让它们出现在该出现的地方。下一步就是进行绘制了,浏览器将会遍历render树,每一个节点都会被UI后端层所绘制。

很重要的一点是,这整个过程是渐进性的。为了更好的用户体验,渲染引擎会尽快地解析内容到屏幕上。它并不会等到html完全被解析才开始创建和布局render树。一部分内容被解析了,那它就会立刻被绘制到页面上,这这个过程中,浏览器可能还在请求剩余部分的内容。

主要流程实例

webkitflow.png

图3 :Webkit 主要流程

image008.jpg

图4 :Mozilla 的Gecko渲染引擎主要流程

从图3和图4你可以看到,虽然Webkit和Gecko在某些术语上稍有不同,但是主要流程是基本相同的。

Gecko把可见的格式化元素组成的树为“Frame”树。每一个元素都是一个frame。Webkit则把每一个渲染对象组成的树称为render树。对每一个元素的定位,Webkit称为布局,而Gecko称为回流。Webkit称利用dom节点及样式信息去构建render树的过程为attachment,Gecko在html和dom树之间附加了一层,这层称为内容接收器,相当制造dom元素的工厂。下面将讨论流程中的各个阶段。

解析

解析是渲染引擎执行过程中非常重要的部分,我们将会稍微深入地去探讨一下。让我们先来简单介绍一下什么是解析。

解析一个文档意味着需要将内容翻译成某种编码能够理解和使用的结构。而解析的结果通常是能够表达文档结构的节点树。它被称为解析树或语法树。

举例来说,解析表达式“2+3-1”,应该返回如下的树:

image009.png

图5:数学表达式的树结构

语法

解析过程依赖于文档遵从的语法规则——文档的语言或格式。每种可解析的格式必须具有由词汇及语法规则组成的特定的文法,这被称为上下文无关文法。人类的语言不具有这一特点,所以不能被常规的解析技术所解析。

解析器-词法分析器

解析过程可以被分为两个过程-词法分析和语法分析。

词法分析是把输入解释成符号的过程,而符号,是组成语言的基本有效单元。它相当于字典中所有的单词,用以组成和表现人类语言。

语法分析是指应用语法规则。

通常情况下,解析器将工作分配给两个组件 - 词法分析器(有时也被称作标记解析器)主要负责把输入分解成合法的符号,语法分析器主要负责依靠语法规则来分析文档结构,并构建出解析树。词法分析器知道如何跳过类似空白符或者换行符之类的无关字符。

image011.png

图6:从源文档到解析树

解析过程是重复迭代的。解析器将会从词法分析器获取一个新符号,并且尝试用某一种语法规则去匹配它。如果有规则匹配到了,那么该符号相应的节点将会被添加到解析树中,然后解析器会接着解析下一个符号。

如果没有规则可以匹配该符号,解析器将会在内部保存下这个符号,并继续获取下一个符号,直到有一条语法规则可以匹配所有内部存储的符号。如果到最后还是没有找到能够匹配的规则,那么解析器将会抛出一个异常。这意味着该文档不合法或者有语法错误。

转换过程

通常情况下,解析树并不是最终的结果。解析通常在转换过程中使用,而转换用于将输入文档转成另一种格式。编译过程就是一个例子。编译器将源代码编译成机器码时,首先做的就是把它解析成解析树,然后再将解析树转化成机器码文档。

image013.png

图7:编译流程

解析实例

在图5中,我们基于一段数学表达式创建了一棵解析树。让我们来尝试定义一门简单的数学语言,然后看看解析过程。

词汇表:我们的语言包括了整数、加号和减号。

语法:

  1. 我们的语言的基本组成时表达式、术语和操作符

  2. 可以包含多个表达式

  3. 两个术语(term)通过操作符连接,这就形成一个表达式

  4. 操作符只能是加号或减号

  5. 一个术语(term)只能是一个整数或者一个表达式

让我们来分析一下输入“2+3-1”后发生了什么。

第一个匹配到规则的子串是“2”,根据规则5,它是一个术语(term)。第二个匹配到规则的是“2+3”,它匹配到第三条语法规则。下一次匹配将会在这个输入的最后。“2+3-1”是一段表达式,因为我们已经知道“2+3”是一个术语(term),接下去的“-”是一个操作符,再后面“1”是一个整数,也就是术语(term),这匹配了规则3。而“2++”不会匹配任何语法,所以它是一个非法输入。


cucumber
192 声望7 粉丝