当前位置: 首页 > Web前端 > HTML5

浏览器原理--编译过程初探

时间:2023-04-05 20:17:53 HTML5

原创不易,如需转载请【联系作者】或【署名作者并注明文章出处】浏览器介绍浏览器infrastructure浏览器的主要组件渲染引擎的基本工作流程Parsing&DOMtreeconstruction分析过程编译过程DEMO2+3-1词法分析:这种语言可以包含整数,加号和减号。句法分析:句法构建块是表达式、术语、操作。语言可以包含任意数量的表达式。表达式定义为:一个术语后跟一个操作,然后是另一个术语。运算是加号或减号,项是整数或表达式。HTML解析遵循的原则:W3C:HTML词汇和语法规则DTD:文档类型定义文档类型声明软语法!==XMLXHTMLDOM文档对象模型让我们看一个示例,该示例被解析为流畅语言的容错特性的解析算法:浏览器容错以支持众所周知的无效HTML情况。解析过程是可重入的。document.write标记算法DOM树构造算法创建解析器时,也会创建Document对象。在树构建阶段,包含Document根节点的DOM树将被改变,元素将被添加到DOM树中。标记器释放的每个节点将由树构建器处理。对于每一个token,规范都会定义它对应的DOM元素,并为该元素创建这个DOM元素。除了将元素添加到DOM树之外,它还会将元素添加到开放元素堆中。该堆用于修复嵌套错误和未关闭的元素。构造算法以状态机的形式表示。这些状态称为“嵌入模式”。在解析结束时,浏览器将文档标记为交互式并开始以“延迟”模式解析脚本——在文档被解析后执行。此时,文档状态变为“完成”并引发“加载”事件。浏览器容错在HTML页面上,“无效语法”(InvalidSyntax)错误绝不会出现。浏览器修复它并继续运行。浏览器容错机制CSSparser解析JS网络模型是同步的[Synchronousasyncdefer]pre-parsing当有样式加载和解析时,Firefox会屏蔽所有脚本。Webkit只会阻止脚本尝试获取可能受未加载样式影响的特定样式属性。渲染树构建渲染引擎webkit主进程基本工作流程Gecko主进程渲染树由可视化元素组成,这些元素按照要显示的顺序排列。它是文档的可视化表示。渲染树的目的是保证内容的绘制是有序的。渲染器知道如何布局和绘制自身及其子类。Firefox将渲染树中的元素称为“框架”。Webkit将这些元素称为“渲染器”或“渲染对象”。webkit盒模型渲染树的构建1渲染器对应DOM元素,但不是一对一的关系。非可视元素不会插入到渲染树中,例如head元素。display!==visibility2有些DOM元素会对应多个可视对象。有些元素具有复杂的结构,因此无法用单个矩形表示。比如select元素有3个renderer3当文本无法在一行中显示而被拆分成多行时,新行中的文本将被添加到新的renderer中。4如果内联元素同时包含内联元素和块级元素,则会创建匿名块级渲染器来包装这些内联元素。5有些渲染对象与DOM节点是一一对应的,但是在树中的位置不同。浮动和绝对定位的元素从流中取出,放置在树中的不同位置,然后映射到实际的框架。它们存在于占位符框架中。渲染树和对应的DOM树,Viewport是初始包含块。在Webkit中,Viewport是一个RenderView对象。在Webkit中,分解样式和创建渲染器的过程称为“附件”。每个DOM节点都有一个附加方法。“attach”是同步的,向DOM树中插入一个节点会调用新节点的attach方法。在Firefox中,构建过程表现为注册DOM更新的侦听器,然后将框架创建委托给“框架构建器”,它分解样式以创建框架。样式计算构建渲染树需要计算每个渲染对象的视觉属性。通过计算每个元素的样式属性来完成样式计算带来了一定的难度。1.样式数据结构庞大,包括很多样式属性,可能会造成内存问题。2.如果不优化,那么为每个元素寻找匹配规则,会造成性能问题。为遍历整个规则表的每个元素找到匹配项是一项繁重的任务。选择器可以有复杂的结构,这会导致匹配过程开始匹配看起来有希望但实际上无效的路径,然后尝试新的匹配路径。3.应用规则涉及定义规则层次结构的非常复杂的级联规则。共享样式数据Webkit节点引用样式对象(RenderStyle)。在某些情况下,这些对象可以在节点之间共享。这些节点是兄弟节点并且:1.这些元素必须处于相同的鼠标状态(例如,一个不能处于:hover状态而另一个则不是)2.元素不应该有ID3,标签名称应该匹配4.类attributes应该可以匹配5.映射的属性集必须相同6.链接状态必须匹配7.焦点状态必须匹配8.元素不能被属性选择器影响,属性选择器定义为可以匹配中任意属性的属性选择元素设备。9.元素不能有内联样式属性。10.不能使用兄弟选择器。当WebCore遇到兄弟选择器时,它会抛出一个全局开关,关闭整个文档的样式共享。这些选择器包括:+选择器、:first-child和:last-child等。Firefox规则树(Firefoxruletree)为了更容易进行样式计算,Firefox提供了两种树规则树和样式上下文树。Webkit也有样式对象,但不是将它们存储在类似于样式上下文树的树中,它只是具有指向相应样式的DOM节点。渐进过程:Webkit使用一个标志来标记何时加载顶级样式表(包括@imports)。在使用某个样式时,如果发现该样式还没有完全加载,则会使用占位符在文档中进行标记。加载样式时,将重新计算。当创建Layout&PaintingLayout渲染器并将其添加到渲染树时,它没有位置和大小。计算这些值的过程称为布局和回流。HTML使用基于流的布局模型,从左到右,从上到下。但也有例外——比如表格,需要计算多次(3.5)。坐标系与根框架相关,使用上左坐标。布局是一个递归过程。从根渲染器开始,对应于HTML文档的元素。布局通过部分或所有这些帧层次结构递归地继续,计算每个渲染器的几何信息。根渲染器的位置是0,0,它的大小是视口大小——浏览器窗口的可见部分。所有渲染器都有布局(layout)和回流(reflow)方法,每个渲染器都会调用那些需要布局的子渲染器的布局方法。肮脏的价值系统为了避免每个小变化的完整布局,浏览器使用了肮脏的价值系统。更改或添加的渲染器会将其自身及其子项标记为“脏”——需要布局。有两个标志——“脏”和“孩子脏”。后者意味着虽然渲染器本身没有问题,但它至少有一个子项需要布局。布局过程通常有以下几种模式:父渲染器确定自己的宽度父渲染器遍历子渲染器,然后放置子渲染器(设置其x和y)如果需要,调用子渲染器的布局(layout)方法-它们很脏,或者我们处于全局布局中,或者其他原因-这会计算子渲染器的高度。父渲染器使用子渲染器的高度、边距和填充的累积高度来设置自己的高度——父渲染器的父渲染器也使用这个高度。将脏值设置为false。当渲染器在布局过程中发现需要断线时,它会停止并通知父渲染器需要断线。父渲染器会创建额外的渲染器,然后调用这些渲染器的布局方法。绘画在绘画阶段,遍历渲染器树,调用渲染器的paint方法,将内容排列在屏幕上。绘图使用UI基本组件CSS2规定了绘图程序的顺序。这实际上是元素在堆叠上下文中堆叠的顺序。一个块级渲染器的堆叠顺序如下:背景色(backgroundcolor)背景图(backgroundimage)边框(edge)孩子(children)轮廓(outline)不易,如需转载请【联系作者】或【署名作者并注明文章出处】