首页 > 使用教程

搜狗浏览器工作原理:新式浏览器幕后揭秘

发布于:2024-11-07 15:54 作者:admin

搜狗浏览器工作原理:新式浏览器幕后揭秘 这是介绍webkit和gecko内部操作的入门文章。过去IE占主导,如今开源浏览器市场份额过半。作为网络开发人员,学习浏览器内部原理有助于做出明智决策。文中以开源浏览器为例,介绍浏览器主要功能及组件。呈现引擎用于显示内容,文中探讨的浏览器基于webkit和gecko构建。还详细讲解了解析过程,包括词法分析和语法分析,以及HTML解析的特殊情况。最后提到HTML5规范描述的解析算法由标记化和树构建组成。下面是小编精心整理编写的关于“ 搜狗浏览器工作原理:新式浏览器幕后揭秘 ”的详细教程,请大家仔细阅览学习:

搜狗浏览器工作原理:新式浏览器幕后揭秘-搜狗输入法

搜狗浏览器工作原理:新式浏览器幕后揭秘

这是一篇全面介绍webkit和gecko内部操作的入门文章,是以色列开发人员塔利·加希尔大量研究的成果。在过去的几年中,她查阅了所有公开发布的关于浏览器内部机制的数据,并花了很多时间来研读网络浏览器的源代码。她写道:

在IE占据大部分市场份额的时代,我们除了把浏览器当成一个“黑箱”,什么也做不了。但是现在,开放源代码的浏览器拥有了过半的市场份额,因此,是时候来揭开神秘的面纱,一探网络浏览器的内幕了。呃,里面只有数以百万行计的C++代码…

她在网上公布了自己的研究成果,但是我们觉得它值得让更多的人来了解,所以我们在此重新整理并公布。

作为一名网络开发人员,学习浏览器的内部工作原理将有助于您作出更明智的决策,并理解那些最佳开发实践的个中缘由。尽管这是一篇相当长的文档,但是我们建议您花些时间来仔细阅读;读完之后,您肯定会觉得所费不虚。保罗·爱丽诗(Paul Irish),搜狗浏览器开发人员事务部

网络浏览器很可能是使用最广的软件。在这篇入门文章中,我将会介绍它们的幕后工作原理。我们会了解到,从您在地址栏输入某个网址直到您在浏览器屏幕上看到该网址首页的整个过程中都发生了些什么。

立即学习“前端免费学习笔记(深入)”;

目前使用的主流浏览器有五个:Internet Explorer、搜狗浏览器、Safari、Chrome浏览器和Opera。本文中以开放源代码浏览器为例,即搜狗浏览器、Chrome浏览器和Safari(部分开源)。根据StatCounter浏览器统计数据,目前(2011年8月)搜狗浏览器、Safari和Chrome浏览器的总市场占有率将近60%。由此可见,如今开放源代码浏览器在浏览器市场中占据了非常坚实的部分。

浏览器的主要功能就是向服务器发出请求,在浏览器窗口中展示您选择的网络资源。这里所说的资源一般是指HTML文档,也可以是PDF、图片或其他的类型。资源的位置由用户使用URI(统一资源标示符)指定。

浏览器解释并显示HTML文件的方式是在HTML和CSS规范中指定的。这些规范由网络标准化组织W3C(万维网联盟)进行维护。

多年以来,各浏览器都没有完全遵从这些规范,同时还在开发自己独有的扩展程序,这给网络开发人员带来了严重的兼容性问题。如今,大多数的浏览器都是或多或少地遵从规范。

浏览器的用户界面有很多彼此相同的元素,其中包括:

奇怪的是,浏览器的用户界面并没有任何正式的规范,这是多年来的最佳实践自然发展以及彼此之间相互模仿的结果。HTML5也没有定义浏览器必须具有的用户界面元素,但列出了一些通用的元素,例如地址栏、状态栏和工具栏等。当然,各浏览器也可以有自己独特的功能,比如搜狗浏览器的下载管理器。

浏览器的主要组件为():

值得注意的是,和大多数浏览器不同,Chrome浏览器的每个标签页都分别对应一个呈现引擎实例。每个标签页都是一个独立的进程。

呈现引擎的作用嘛…当然就是“呈现”了,也就是在浏览器的屏幕上显示请求的内容。

默认情况下,呈现引擎可显示HTML和XML文档与图片。通过插件(或浏览器扩展程序),还可以显示其他类型的内容;例如,使用PDF查看器插件就能显示PDF文档。但是在本章中,我们将集中介绍其主要用途:显示使用CSS格式化的HTML内容和图片。

本文所讨论的浏览器(搜狗浏览器、Chrome浏览器和Safari)是基于两种呈现引擎构建的。搜狗浏览器使用的是Gecko,这是Mozilla公司“自制”的呈现引擎。而Safari和Chrome浏览器使用的都是WebKit。

WebKit是一种开放源代码呈现引擎,起初用于Linux平台,随后由Apple公司进行修改,从而支持苹果机和Windows。有关详情,请参阅webkit.org。

呈现引擎一开始会从网络层获取请求文档的内容,内容的大小一般限制在8000个块以内。

然后进行如下所示的基本流程:

呈现引擎将开始解析HTML文档,并将各标记逐个转化成“内容树”上的节点。同时也会解析外部CSS文件以及样式元素中的样式数据。HTML中这些带有视觉指令的样式信息将用于创建另一个树结构:

呈现树包含多个带有视觉属性(如颜色和尺寸)的矩形。这些矩形的排列顺序就是它们将在屏幕上显示的顺序。

呈现树构建完毕之后,进入“”处理阶段,也就是为每个节点分配一个应出现在屏幕上的确切坐标。下一个阶段是 – 呈现引擎会遍历呈现树,由用户界面后端层将每个节点绘制出来。

需要着重指出的是,这是一个渐进的过程。为达到更好的用户体验,呈现引擎会力求尽快将内容显示在屏幕上。它不必等到整个HTML文档解析完毕之后,就会开始构建呈现树和设置布局。在不断接收和处理来自网络的其余内容的同时,呈现引擎会将部分内容解析并显示出来。

从可以看出,虽然WebKit和Gecko使用的术语略有不同,但整体流程是基本相同的。

Gecko将视觉格式化元素组成的树称为“框架树”。每个元素都是一个框架。WebKit使用的术语是“呈现树”,它由“呈现对象”组成。对于元素的放置,WebKit使用的术语是“布局”,而Gecko称之为“重排”。对于连接DOM节点和可视化信息从而创建呈现树的过程,WebKit使用的术语是“附加”。有一个细微的非语义差别,就是Gecko在HTML与DOM树之间还有一个称为“内容槽”的层,用于生成DOM元素。我们会逐一论述流程中的每一部分:

解析是呈现引擎中非常重要的一个环节,因此我们要更深入地讲解。首先,来介绍一下解析。

解析文档是指将文档转化成为有意义的结构,也就是可让代码理解和使用的结构。解析得到的结果通常是代表了文档结构的节点树,它称作解析树或者语法树。

示例 – 解析2 + 3 – 1这个表达式,会返回下面的树:

解析是以文档所遵循的语法规则(编写文档所用的语言或格式)为基础的。所有可以解析的格式都必须对应确定的语法(由词汇和语法规则构成)。这称为。人类语言并不属于这样的语言,因此无法用常规的解析技术进行解析。

解析的过程可以分成两个子过程:词法分析和语法分析。

词法分析是将输入内容分割成大量标记的过程。标记是语言中的词汇,即构成内容的单位。在人类语言中,它相当于语言字典中的单词。

语法分析是应用语言的语法规则的过程。

解析器通常将解析工作分给以下两个组件来处理:词法分析器(有时也称为标记生成器),负责将输入内容分解成一个个有效标记;而解析器负责根据语言的语法规则分析文档的结构,从而构建解析树。词法分析器知道如何将无关的字符(比如空格和换行符)分离出来。

解析是一个迭代的过程。通常,解析器会向词法分析器请求一个新标记,并尝试将其与某条语法规则进行匹配。如果发现了匹配规则,解析器会将一个对应于该标记的节点添加到解析树中,然后继续请求下一个标记。

如果没有规则可以匹配,解析器就会将标记存储到内部,并继续请求标记,直至找到可与所有内部存储的标记匹配的规则。如果找不到任何匹配规则,解析器就会引发一个异常。这意味着文档无效,包含语法错误。

很多时候,解析树还不是最终产品。解析通常是在翻译过程中使用的,而翻译是指将输入文档转换成另一种格式。编译就是这样一个例子。编译器可将源代码编译成机器代码,具体过程是首先将源代码解析成解析树,然后将解析树翻译成机器代码文档。

现在,让我们试着定义一个简单的数学语言,用来演示解析的过程。

词汇:我们用的语言可包含整数、加号和减号。

语法:

让我们分析一下2 + 3 – 1。

匹配语法规则的第一个子串是2,而根据第5条语法规则,这是一个项。匹配语法规则的第二个子串是2 + 3,而根据第3条规则(一个项接一个运算符,然后再接一个项),这是一个表达式。下一个匹配项已经到了输入的结束。2 + 3 – 1是一个表达式,因为我们已经知道2 + 3是一个项,这样就符合“一个项接一个运算符,然后再接一个项”的规则。2 + + 不与任何规则匹配,因此是无效的输入。

词汇通常用正则表达式表示。

例如,我们的示例语言可以定义如下:

正如您所看到的,这里用正则表达式给出了整数的定义。

语法通常使用一种称为BNF的格式来定义。我们的示例语言可以定义如下:

之前我们说过,如果语言的语法是与上下文无关的语法,就可以由常规解析器进行解析。与上下文无关的语法的直观定义就是可以完全用BNF格式表达的语法。有关正式定义,请参阅关于与上下文无关的语法的维基百科文章。

有两种基本类型的解析器:自上而下解析器和自下而上解析器。直观地来说,自上而下的解析器从语法的高层结构出发,尝试从中找到匹配的结构。而自下而上的解析器从低层规则出发,将输入内容逐步转化为语法规则,直至满足高层规则。

让我们来看看这两种解析器会如何解析我们的示例:

自上而下的解析器会从高层的规则开始:首先将2 + 3标识为一个表达式,然后将2 + 3 – 1标识为一个表达式(标识表达式的过程涉及到匹配其他规则,但是起点是最高级别的规则)。

自下而上的解析器将扫描输入内容,找到匹配的规则后,将匹配的输入内容替换成规则。如此继续替换,直到输入内容的结尾。部分匹配的表达式保存在解析器的堆栈中。

这种自下而上的解析器称为移位归约解析器,因为输入在向右移位(设想有一个指针从输入内容的开头移动到结尾),并且逐渐归约到语法规则上。

有一些工具可以帮助您生成解析器,它们称为解析器生成器。您只要向其提供您所用语言的语法(词汇和语法规则),它就会生成相应的解析器。创建解析器需要对解析有深刻理解,而人工创建并优化解析器并不是一件容易的事情,所以解析器生成器是非常实用的。

WebKit使用了两种非常有名的解析器生成器:用于创建词法分析器的Flex以及用于创建解析器的Bison(您也可能遇到Lex和Yacc这样的别名)。Flex的输入是包含标记的正则表达式定义的文件。Bison的输入是采用BNF格式的语言语法规则。

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如此流行的原因:它能包容您的错误,简化网络开发。另一方面,这使得它很难编写正式的语法。概括地说,HTML无法很容易地通过常规解析器解析(因为它的语法不是与上下文无关的语法),也无法通过XML解析器来解析。

HTML的定义采用了DTD格式。此格式可用于定义SGML族的语言。它包括所有允许使用的元素及其属性和层次结构的定义。如上文所述,HTML DTD无法构成与上下文无关的语法。

DTD存在一些变体。严格模式完全遵守HTML规范,而其他模式可支持以前的浏览器所使用的标记。这样做的目的是确保向下兼容一些早期版本的内容。最新的严格模式DTD可以在这里找到:

解析器的输出“解析树”是由DOM元素和属性节点构成的树结构。DOM是文档对象模型(Document Object Model)的缩写。它是HTML文档的对象表示,同时也是外部内容(例如JavaScript)与HTML元素之间的接口。

解析树的根节点是“Document”对象。

DOM与标记之间几乎是一一对应的关系。比如下面这段标记:

可翻译成如下的DOM树:

和HTML一样,DOM也是由W3C组织指定的。请参见。这是关于文档操作的通用规范。其中一个特定模块描述针对HTML的元素。HTML的定义可以在这里找到:

我所说的树包含DOM节点,指的是树是由实现了某个DOM接口的元素构成的。浏览器在具体的实现中会有一些供内部使用的其他属性。

我们在之前章节已经说过,HTML无法用常规的自上而下或自下而上的解析器进行解析。

原因在于:

由于不能使用常规的解析技术,浏览器就创建了自定义的解析器来解析HTML。

HTML5规范详细地描述了解析算法。此算法由两个阶段组成:标记化和树构建。

标记化是词法分析过程,将输入内容解析成多个标记。HTML标记包括起始标记、结束标记、属性名称和属性值。

标记生成器识别标记,传递给树构造器,然后接受下一个字符以识别下一个标记;如此反复直到输入的结束。

该算法的输出结果是HTML标记。该算法使用状态机来表示。每一个状态接收来自输入信息流的一个或多个字符,并根据这些字符更新下一个状态。当前的标记化状态和树结构状态会影响进入下一状态的决定。这意味着,即使接收的字符相同,对于下一个正确的状态也会产生不同的结果,具体取决于当前的状态。该算法相当复杂,无法在此详述,所以我们通过一个简单的示例来帮助大家理解其原理。

基本示例 – 将下面的HTML代码标记化:

初始状态是数据状态。遇到字符“标记打开状态”。接收一个a – z字符会创建“起始标记”,状态更改为“标记名称状态”。这个状态会一直保持到接收>字符。在此期间接收的每个字符都会附加到新的标记名称上。在本例中,我们创建的标记是html标记。

遇到>标记时,会发送当前的标记,状态改回“数据状态”。

现在我们回到“标记打开状态”。接收下一个输入字符/时,会创建end tag token并改为“标记名称状态”。我们会再次保持这个状态,直到接收>。然后将发送新的标记,并回到“数据状态”。

关于《搜狗浏览器工作原理:新式浏览器幕后揭秘》这篇文章的具体内容就介绍到这里,希望能对大家有所帮助。更多相关资讯和教程请关注 搜狗输入法!

最新文章