【浏览器渲染原理】解析和DOM树构建之HTML解析器

HTML解析器的任务是将HTML标记解析成解析树。

HTML的词汇和语法在W3C规范中进行了定义。

HTML的定义采用了DTD(DocumentType Definition,文档类型定义)。

解析树是由DOM(Document Object Model)元素和属性节点构成的树结构,根节点是Document对象。

DOM与标记是一一对应的。

<html>  

        <body>    

               <p>HelloWorld</p>    

               <div><img src="example.png"/></div>  

        </body>

</html>

上面这段代码对应的DOM树如下图:



HTML无法用常规的自上而下或自下而上的解析器进行解析,原因如下:

1)        HTML允许省略某些隐式添加的标记,可以省略起始或结束标签。HTML的语法不是上下文无关的语法。

2)        浏览器可以接受一些常见的无效HTML用法。

3)        解析过程需要不断反复。在脚本标记中添加document.write,可以添加HTML标记,在解析过程中更改了输入内容。

基于上述原因,浏览器创建了自定义的解析器来解析HTML。解析算法分为标记化和树构建。标记化是词法分析过程,将输入内容解析成多个标记。HTML标记包括起始标记、结束标记、属性名称和属性值。标记生成器识别标记,传递给树构造器,然后接受下一个字符以识别下一个标记;直到输入的结束。

1 标记化算法

标记化算法的输入结果是HTML标记,使用状态机表示。状态机一共有4个状态:数据状态(Data)、标记打开状态(Tag open)、标记名称状态(Tag name)、关闭标记打开状态(Close tag open state)。

初始状态是数据状态。

当标记是处于数据状态时,

       1)遇到字符<时,状态更改为“标记打开状态”:

              a. 接收一个a-z字符会创建“起始标记”,状态更改为“标记名称状态”,并保持到接收>字符。此期间的字符串会形成一个新的标记名称。接收到>标记后,将当前的新标记发送给树构造器,状态改回“数据状态”。

              b. 接收下一个输入字符/时,会创建关闭标记打开状态,并更改为“标记名称状态”。直到接收>字符,将当前的新标记发送给树构造器,并改回“数据状态”。

       2)遇到a-z字符时,会将每个字符创建成字符标记,并发送给树构造器。


举个例子:

<html>
	<body>
		Hello world
	</body>
</html>

上述的代码片段标记化之后,发送给树构造器的顺序如下:

html开始标记、body开始标记、H字符、e字符、l字符、l字符、o字符、空格字符、w字符、o字符、r字符、l字符、d字符、body结束标记、html结束标记、文件结束标记

2 树构建算法

在创建解析器的同时,也会创建Document对象。在树构建阶段,以Document为根节点的DOM树也会不断进行修改,添加各种元素。标记生成器发送的每个节点都会由树构建器进行处理。每个标记都有对应的DOM元素,这些元素会在接收到标记时创建。

开放元素的堆栈:添加到DOM树中的元素也会添加到开放元素的堆栈中,用于纠正嵌套错误和处理未关闭的标记。

树构建算法可以用状态机来描述,称为“插入模式”。

树构建阶段的输入是一个来自标记化阶段的标记序列。以上例来说明,第一个模式是“initial mode”。接收HTML标记后转为“before html”,并在这个模式下创建一个HTMLHtmlElement元素,并将其附加到Document根对象上。状态改为“before head”。此时接收到“body”标记,系统创建一个HTMLHeadElement,并添加到树中,然后进入“in head”模式,然后转入“after head”模式。系统对body标记重新处理,创建HTMLBodyElement并插入到DOM树,模式变为“in body”。然后接收到“H”字符标记,创建Text节点。后面的“ello world”字符标记也被附加到了这个Text节点上。接收到body结束标记时,系统进入“after body”模式。在接收到html结束标记时,进入“after after body”模式。接收到文件结束标记后,解析过程结束。


在解析的过程中,浏览器会将文档标注为交互状态,并开始解析出于“deferred”模式的脚本,这些脚本是应在文档解析完成后才执行的脚本。当文档状态为“完成”时,会触发一个“加载”事件。

【参考资料】

http://www.html5rocks.com/zh/tutorials/internals/howbrowserswork/#The_browsers_we_will_talk_about

http://taligarsiel.com/Projects/howbrowserswork1.htm



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值