浏览器解析HTML的过程及DOM的树形结构 转载
浏览器解析HTML的过程及DOM的树形结构
渲染引擎
渲染引擎的职责是……渲染,也就是把请求的内容显示到浏览器屏幕上。默认情况下渲染引擎可以显示HTML,XML文档以及图片。 通过插件(浏览器扩展)它可以显示其它类型文档。比如使用PDF viewer插件显示PDF文件。
我们提到的Firefox, Safari两种浏览器构建于两种渲染引擎之上:Firefox使用Gecko ——
Mozilla自家的渲染引擎;Safari 和 Chrome 都使用 Webkit。Webkit
是一个开源的渲染引擎,它源自Linux平台上的一个引擎,经过Apple公司的修改可以支持Mac与Windows平台。
主要流程
渲染引擎开始于从网络层获取请求内容,一般是不超过8K的数据块。接下来就是渲染引擎的基本工作流程:
解析HTML构建DOM树,渲染树构建,渲染树布局,绘制渲染树
渲染引擎会解析HTML文档并把标签转换成内容树中的DOM节点。它会解析style元素和外部文件中的样式数据。样式数据和HTML中的显示控制将共同
用来创建另一棵树——渲染树。渲染树包含带有颜色,尺寸等显示属性的矩形。这些矩形的顺序与显示顺序一致。
渲染树构建完成后就是"布局"处理,也就是确定每个节点在屏幕上的确切显示位置。下一个步骤是绘制 ——
遍历渲染树并用UI后端层将每一个节点绘制出来。一定要理解这是一个缓慢的过程,为了更好的用户体验,渲染引擎会尝试尽快的把内容显示出来。它不会等到所
有HTML都被解析完才创建并布局渲染树。它会在处理后续内容的同时把处理过的局部内容先展示出来。
主要流程示例

Webkit主要流程

Mozilla的Gecko渲染引擎主要流程
尽管Webkit与Gecko使用略微不同的术语,这个过程还是基本相同的。Gecko 里把格式化好的可视元素称做"帧树"(Frame
tree)。每个元素就是一个帧(frame)。 Webkit 则使用"渲染树"这个术语,渲染树由"渲染对象"组成。Webkit
里使用"layout"表示元素的布局,Gecko则称为"Reflow"。Webkit使用"Attachment"来连接DOM节点与可视化信息以构
建渲染树。一个非语义上的小差别是Gecko在HTML与DOM树之间有一个附加的层 ,称作"content sink",是创建DOM对象的工厂。
解析
因为解析是渲染引擎中一个很重要的处理,解析一个文档意味着把它翻译成有意义的结构以供代码使用。解析的结果通常是一个表征文档的由节点组成的树,称为解析树或句法树。
解析表达式"2 + 3 – 1″可以返回下面的树:

数学表达式树节点
语法
解析是基于文档所遵循的语法规则——书写所用的语言或格式——来进行的。每一种可以解析的格式必须由确定的语法与词汇组成。这被称之为上下文无关语法。人类语言并非此种语言,所以不能用常规的解析技术来解析。
解析器——词法分析器组合
解析器有两个处理过程——词法分析与句法分析。词法分析负责把输入切分成符号序列,符号是语言的词汇——由该语言所有合法的单词组成。句法分析是对该语言
句法法则的应用。解析器通常把工作分给两个组件——分词程序负责把输入切分成合法符号序列,解析程序负责按照句法规则分析文档结构和构建句法树。词法分析
器知道如何过滤像空格,换行之类的无关字符。

从源文档到解析树(文档,词法分析,句法分析,解析树)
解析过程是交互式的。解析器通常会从词法分析器获取新符号并尝试匹配句法规则。如果匹配成功,就在句法树上创建相应的节点,并继续从词法分析器获取下一个
符号。如果没有匹配的规则,解析器会内部保存这个符号,并继续从词法分析器获取符号,直到内部保存的所有符号能够成功匹配一个规则。如果最终无法匹配,解
析器会抛出异常。这意味着文档无效,含有句法错误。
转换
多数情况下解析树并非最终结果。解析经常是为了从输入文档转换成另外一种格式。比如编译器要把源码编译成机器码,会首先解析成解析树,再把解析树转换成机器码。

编译过程(源码,解析,解析树,转换,机器码)
词法与句法的合法性定义
词汇通常用正则表达式来表示。比如我们的语言可以定义为:
INTEGER :0|[1-9][0-9]*
PLUS : +
MINUS: -
如你所见,整型是由正则表达式定义的。句法常用BNF格式定义,我们的语言被定义为:
expression := term operation term
operation := PLUS | MINUS
term := INTEGER | expression
我们说过常规解析器只能解析上下文无关语法的语言。这种语言的一个直觉的定义是它的句法可以用BNF完整的表达。Webkit使用两款知名的解析器生成工
具:Flex用于创建词法分析器,Bison用于创建解析器
(你也许会看到它们以Lex和Yacc的名字存在)。Flex的输入文件是符号的正则表达式定义,Bison的输入文件是BNF格式的句法定义。
HTML解析器
HTML解析器的工作是解析HTML标记到解析树。
HTML语法定义
HTML的词汇与句法定义在w3c组织创建的规范中。当前版本是HTML4,HTML5的工作正在进行中。
不是上下文无关语法
在对解析器的介绍中看到,语法可以用类似BNF的格式规范地定义。不幸的是所有常规解析器的讨论都不适用于HTML(我提及它们并不是为了娱乐,它们可以
用于解析CSS和JavaScript)。HTML无法用解析器所需的上下文无关的语法来定义。过去HTML格式规范由DTD (Document
Type Definition)来定义,但它不是一个上下文无关语法。
HTML与XML相当接近。XML有许多可用的解析器。HTML还有一个
XML变种叫XHTML,那么它们主要区别在哪里呢?区别在于HTML应用更加"宽容",它容许你漏掉一些开始或结束标签等。它整个是一个"软"句法,不
像XML那样严格死板。
总的来说这一看似细微的差别造成了两个不同的世界。一方面这使得HTML很流行,因为它包容你的错误,使网页作者的生活变得轻松。另一方面,它使编写语法
格式变得困难。所以综合来说,HTML解析并不简单,现成的上下文相关解析器搞不定,XML解析器也不行。
HTML DTD
HTML的定义使用DTD文件。这种格式用来定义SGML族语言,它包含对所有允许的元素的定义,包括它们的属性和层级关系。如我们前面所说,HTML
DTD构不成上下文无关语法。DTD有几种不同类型。严格模式完全尊守规范,但其它模式为了向前兼容可能包含对早期浏览器所用标签的支持。
DOM
解析器输出的树是由DOM元素和属性节点组成的。DOM的全称为:Document Object Model。它是HTML文档的对象化描述,也是HTML元素与外界(如Javascript)的接口。
DOM与标签几乎有着一一对应的关系,如下面的标签
<html>
<body>
<p> Hello World p>
<div> <img src="example.png"/>div>
body>
html>
会被转换成如的DOM树:

当我们说树中包含DOM节点时,意思就是这个树是由实现了DOM接口的元素组成。这些实现包含了其它一些浏览器内部所需的属性。
解析算法
如我们前面看到的,HTML无法使用自上而下或自下而上的解析器来解析。理由如下:
语言的宽容特点
浏览器需要对无效HTML提供容错性的事实。
解析过程的反复。通常解析过程中源码不会变化。但在HTML中,script标签包含"document.write"时可以添加内容,即解析过程实际上还会改变源码。
浏览器创建了自己的解析器来解析HTML文档。HTML5规范里对解析算法有具体的说明,解析由两部分组成:分词与构建树。分词属于词法分析部分,它把输
入解析成符号序列。在HTML中符号就是开始标签,结束标签,属性名称和属生值。分词器识别这些符号并将其送入树构建者,然后继续分析处理下一个符号,直
到输入结束。

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)