You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Blink:由 Google 和 Opera Software 开发,在Chrome(28及往后版本)、Opera(15及往后版本)和Yandex浏览器中使用。Blink 其实是 Webkit 的一个分支,添加了一些优化的新特性,例如跨进程的 iframe,将 DOM 移入 JavaScript 中来提高 JavaScript 对 DOM 的访问速度等,目前较多的移动端应用内嵌的浏览器内核也渐渐开始采用 Blink。
渲染引擎的工作流程
浏览器渲染引擎最重要的工作就是将 HTML 和 CSS 文档解析组合最终渲染到浏览器窗口上。如下图所示,渲染引擎在接受到 HTML 文件后主要进行了以下操作:解析 HTML 构建 DOM 树 -> 构建渲染树 -> 渲染树布局 -> 渲染树绘制。
解析 HTML 构建 DOM 树时渲染引擎会将 HTML 文件的便签元素解析成多个 DOM 元素对象节点,并且将这些节点根据父子关系组成一个树结构。同时 CSS 文件被解析成 CSS 规则表,然后将每条 CSS 规则按照「从右向左」的方式在 DOM 树上进行逆向匹配,生成一个具有样式规则描述的 DOM 渲染树。接下来就是将渲染树进行布局、绘制的过程。首先根据 DOM 渲染树上的样式规则,对 DOM 元素进行大小和位置的定位,关键属性如position;width;margin;padding;top;border;...,接下来再根据元素样式规则中的color;background;shadow;...规则进行绘制。
另外,这个过程是逐步完成的,为了更好的用户体验,渲染引擎将会尽可能早的将内容呈现到屏幕上,并不会等到所有的 html 都解析完成之后再去构建和布局 render 树。它是解析完一部分内容就显示一部分内容,同时,可能还在通过网络下载其余内容。
再者,需要注意的是,在浏览器渲染完首屏页面后,如果对 DOM 进行操作会引起浏览器引擎对 DOM 渲染树的重新布局和重新绘制,我们叫做「重排」和「重绘」。
在 DOM 树构建的同时,浏览器还会构建另一个树结构:渲染树。这是由可视化元素按照其显示顺序而组成的树,也是文档的可视化表示。它的作用是让您按照正确的顺序绘制内容。渲染器知道如何布局并将自身及其子元素绘制出来。 WebKits RenderObject 类是所有呈现器的基类,其定义如下:
classRenderObject{virtualvoidlayout();virtualvoidpaint(PaintInfo);virtualvoidrectrepaintRect();Node*node;//the DOM nodeRenderStyle*style;// the computed styleRenderLayer*containgLayer;//the containing z-index layer}
渲染器是和 DOM 元素相对应的,但并非一一对应。非可视化的 DOM 元素不会插入呈现树中,例如“head”元素。如果元素的 display 属性值为“none”,那么也不会显示在渲染树中(但是 visibility 属性值为“hidden”的元素仍会显示)。
有一些 DOM 元素对应多个可视化对象。它们往往是具有复杂结构的元素,无法用单一的矩形来描述。例如,“select”元素有 3 个渲染器:一个用于显示区域,一个用于下拉列表框,还有一个用于按钮。如果由于宽度不够,文本无法在一行中显示而分为多行,那么新的行也会作为新的渲染器而添加
另一个关于多渲染器的例子是格式无效的 HTML。根据 CSS 规范,inline 元素只能包含 block 元素或 inline 元素中的一种。如果出现了混合内容,则应创建匿名的 block 渲染器,以包裹 inline 元素。
渲染树样式计算
假设有这样的HTML代码:
<html><body><divclass="err" id="div1"><p>
this is a <spanclass="big"> big error </span>
this is also a
<spanclass="big"> very big error</span> error
</p></div><divclass="err" id="div2">another error</div></body></html>
前言
浏览器对于前端来说,并不陌生。但是我们往往接触的都是一个黑盒的浏览器,并不知道其内部的工作原理,这篇文章我们主要来研究一下浏览器内部是如何去加载一个页面的。这里大多数是一些理论知识点,读起来可能有点枯燥,此文是笔者在网络上搜寻了大量的文章和资料,整理输出而得。不过耐心的了解一下,对理解一些页面性能加载,浏览器一些怪异的问题还是有很多帮助的。
浏览器的组成
渲染引擎(Rendering engine)
浏览器渲染引擎是由各大浏览器厂商依照 W3C 标准自行研发的,也被称之为「浏览器内核」。目前,市面上使用的主流浏览器内核有5类:
Trident、Gecko、Presto、Webkit、Blink
。Trident:俗称 IE 内核,也被叫做 MSHTML 引擎,目前在使用的浏览器有 IE11 -,以及各种国产多核浏览器中的IE兼容模块。另外微软的 Edge 浏览器不再使用 MSHTML 引擎,而是使用类全新的引擎 EdgeHTML。
Gecko:俗称 Firefox 内核,Netscape6 开始采用的内核,后来的 Mozilla FireFox(火狐浏览器)也采用了该内核,Gecko 的特点是代码完全公开,因此,其可开发程度很高,全世界的程序员都可以为其编写代码,增加功能。因为这是个开源内核,因此受到许多人的青睐,Gecko 内核的浏览器也很多,这也是 Gecko 内核虽然年轻但市场占有率能够迅速提高的重要原因。
Presto:Opera 前内核,为啥说是前内核呢?因为 Opera12.17 以后便拥抱了 Google Chrome 的 Blink 内核,此内核就没了寄托。
Webkit:Safari 内核,也是 Chrome 内核原型,主要是 Safari 浏览器在使用的内核,也是特性上表现较好的浏览器内核。也被大量使用在移动端浏览器上。
Blink:由 Google 和 Opera Software 开发,在Chrome(28及往后版本)、Opera(15及往后版本)和Yandex浏览器中使用。Blink 其实是 Webkit 的一个分支,添加了一些优化的新特性,例如跨进程的 iframe,将 DOM 移入 JavaScript 中来提高 JavaScript 对 DOM 的访问速度等,目前较多的移动端应用内嵌的浏览器内核也渐渐开始采用 Blink。
渲染引擎的工作流程
浏览器渲染引擎最重要的工作就是将 HTML 和 CSS 文档解析组合最终渲染到浏览器窗口上。如下图所示,渲染引擎在接受到 HTML 文件后主要进行了以下操作:
解析 HTML 构建 DOM 树 -> 构建渲染树 -> 渲染树布局 -> 渲染树绘制
。解析 HTML 构建 DOM 树时渲染引擎会将 HTML 文件的便签元素解析成多个 DOM 元素对象节点,并且将这些节点根据父子关系组成一个树结构。同时 CSS 文件被解析成 CSS 规则表,然后将每条 CSS 规则按照「从右向左」的方式在 DOM 树上进行逆向匹配,生成一个具有样式规则描述的 DOM 渲染树。接下来就是将渲染树进行布局、绘制的过程。首先根据 DOM 渲染树上的样式规则,对 DOM 元素进行大小和位置的定位,关键属性如
position;width;margin;padding;top;border;...,接下来再根据元素样式规则中的color;background;shadow;...
规则进行绘制。另外,这个过程是逐步完成的,为了更好的用户体验,渲染引擎将会尽可能早的将内容呈现到屏幕上,并不会等到所有的 html 都解析完成之后再去构建和布局 render 树。它是解析完一部分内容就显示一部分内容,同时,可能还在通过网络下载其余内容。
再者,需要注意的是,在浏览器渲染完首屏页面后,如果对 DOM 进行操作会引起浏览器引擎对 DOM 渲染树的重新布局和重新绘制,我们叫做「重排」和「重绘」。
主流程示例
解析
在呈现引擎中解析是非常重要的环节。解析文档即是将文档转化为有意义的结构,解析后得到的结果通常代表了文档结构的节点树,被称作解析树或语法树。
而解析的过程一般为词法分析和语法分析,词法分析即是大量的标记过程,词法分析器根据特定的字典(语言的词汇)对输入内容进行标记;语法分析即是应用语言语法的过程。不同语言拥有不同的解析器,在这里不做多的赘述,如果想了解更多,可以参考浏览器的工作原理:新式网络浏览器幕后揭秘。在浏览器中,有HTML解析器,CSS解析器,JavaScript解析器等。
HTML解析
HTML解析器概括的来说就是一种特别独特的解析方式,需要有一定的容错性,HTML 无法用常规的自上而下或自下而上的解析器进行解析。原因在于:
由于不能使用常规的解析技术,浏览器就创建了自定义的解析器来解析 HTML,此算法由两个阶段组成:标记化和树构建。
标记化是词法分析过程,将输入内容解析成多个标记。HTML 标记包括起始标记、结束标记、属性名称和属性值。
标记生成器识别标记,传递给树构造器,根据传入的标记生成与之对应的 HTMLElement 然后接受下一个字符以识别下一个标记;如此反复直到输入的结束。这一点有点像 Vue Virtual Dom 的生成过程,也是在不断地标记化输入的 HTML 字符串,根据标签,解析生成对应的 vnode。
CSS解析
CSS 解析器将 CSS 文件解析成 StyleSheet 对象,且每个对象都包含 CSS 规则。CSS 规则对象则包含选择器和声明对象,以及其他与 CSS 语法对应的对象。
渲染树构建
在 DOM 树构建的同时,浏览器还会构建另一个树结构:渲染树。这是由可视化元素按照其显示顺序而组成的树,也是文档的可视化表示。它的作用是让您按照正确的顺序绘制内容。渲染器知道如何布局并将自身及其子元素绘制出来。 WebKits RenderObject 类是所有呈现器的基类,其定义如下:
每一个渲染器都代表了一个矩形的区域,通常对应于相关节点的 CSS 框,这一点在 CSS2 规范中有所描述。它包含诸如宽度、高度和位置等几何信息。
框的类型会受到与节点相关的“display”样式属性的影响。下面这段 WebKit 代码描述了根据 display 属性的不同,针对同一个 DOM 节点应创建什么类型的渲染器。
元素类型也是考虑因素之一,例如表单控件和表格都对应特殊的框架。
在 WebKit 中,如果一个元素需要创建特殊的呈现器,就会替换
createRenderer
方法。呈现器所指向的样式对象中包含了一些和几何无关的信息。渲染树和 DOM 树的关系
渲染器是和 DOM 元素相对应的,但并非一一对应。非可视化的 DOM 元素不会插入呈现树中,例如“head”元素。如果元素的 display 属性值为“none”,那么也不会显示在渲染树中(但是 visibility 属性值为“hidden”的元素仍会显示)。
有一些 DOM 元素对应多个可视化对象。它们往往是具有复杂结构的元素,无法用单一的矩形来描述。例如,“select”元素有 3 个渲染器:一个用于显示区域,一个用于下拉列表框,还有一个用于按钮。如果由于宽度不够,文本无法在一行中显示而分为多行,那么新的行也会作为新的渲染器而添加
另一个关于多渲染器的例子是格式无效的 HTML。根据 CSS 规范,inline 元素只能包含 block 元素或 inline 元素中的一种。如果出现了混合内容,则应创建匿名的 block 渲染器,以包裹 inline 元素。
渲染树样式计算
假设有这样的HTML代码:
还有如下规则:
形成的规则树如下图所示(节点的标记方式为“节点名 : 指向的规则序号”):
结合 DOM Tree 生成的上下文树(Style Context Tree)如下图所示(把CSS Rule结点Attach到DOM Tree上,节点名 : 指向的规则节点):
所以,Firefox基本上来说是通过
CSS
解析 生成CSS Rule Tree
,然后,通过比对DOM
生成Style Context Tree
,然后Firefox通过把Style Context Tree
和其Render Tree(Frame Tree)
关联上,就完成了。注意:Render Tree会
把一些不可见的结点去除掉。而Firefox中所谓的Frame
就是一个DOM结点,不要被其名字所迷惑了。注:Webkit不像Firefox要用两个树来干这个,Webkit也有Style对象,它直接把这个Style对象存在了相应的DOM结点上了。
布局(Layout)
渲染器在创建完成并添加到呈现树时,并不包含位置和大小信息。计算这些值的过程称为布局或重排。坐标系是相对于根框架而建立的,使用的是上坐标和左坐标。
布局是一个递归的过程。它从根渲染器(对应于 HTML 文档的 元素)开始,然后递归遍历部分或所有的框架层次结构,为每一个需要计算的呈现器计算几何信息。
根渲染器的位置左边是 0,0,其尺寸为视口(也就是浏览器窗口的可见区域)。
所有的渲染器都有一个“layout”或者“reflow”方法,每一个渲染器都会调用其需要进行布局的子代的 layout 方法。
这里重要要说两个概念,一个是Reflow,另一个是Repaint。这两个不是一回事。
定位
下面主要介绍一些
postion
和z-index
的知识,详细的可以参考这里参考文献
浏览器的工作原理:新式网络浏览器幕后揭秘
浏览器渲染原理
「前端那些事儿」① 浏览器渲染引擎
The text was updated successfully, but these errors were encountered: