浏览器运行原理
一、浏览器简介
浏览器是指可以显示网页服务器或者文件系统的HTML文件(标准通用标记语言的一个应用)内容,并让用户与这些文件交互的一种软件。
浏览器的主要功能就是向服务器发出请求,在浏览器窗口中展示您选择的网络资源。这里所说的资源一般是指 HTML 文档,也可以是 PDF、
图片或其他的类型。
资源的位置由用户使用URI(统一资源标符)指定。多年以来,各浏览器都没有完全遵从这些规范,同时还在开发自己独有的扩展程序,这给网络开发人员带来了严重的兼容性问题。
如今,大多数的浏览器都是或多或少地遵从规范。
HTML和CSS规范中规定了浏览器解释html文档的方式,由W3C组织对这些规范进行维护,W3C是负责制定web标准的组织。
这些年来,浏览器厂商纷纷开发自己的扩展,对规范的遵循并不完善,这为web开发者带来了严重的兼容性问题。
但是,浏览器的用户界面则差不多,常见的用户界面元素包括:
* 用来输入URI的地址栏
* 前进、后退按钮
* 书签选项
* 用于刷新及暂停当前加载文档的刷新、暂停按钮
* 用于到达主页的主页按钮
目前使用的主流浏览器有五个:Internet Explorer、 Firefox、 Safari、 Chrome 和 Opera。
浏览器按照引擎分类:
* Trident引擎:Internet Explorer
* Webkit引擎:Chrome(28版本后基于blink,blink是webkit的一个分支)和Safari
* Gecko引擎:Firefox
* Presto引擎:早期Opera采用,后用webkit引擎。
二、浏览器的主要构成
浏览器的主要组件包括:
* 用户界面:包括地址栏、后退/前进按钮、书签目录等,也就是你所看到的除了用来显示你所请求页面的主窗口之外的其他部分。
* 浏览器引擎:用来查询及操作渲染引擎的接口。
* 渲染引擎:用来显示请求的内容,例如,如果请求内容为html,它负责解析html及css,并将解析后的结果显示出来。
* 网络:用来完成网络调用,例如http请求,它具有平台无关的接口,可以在不同平台上工作。
* UI后端:用来绘制类似组合选择框及对话框等基本组件,具有不特定于某个平台的通用接口,底层使用操作系统的用户接口。
* JS解释器:用来解释执行JS代码。
* 数据存储:属于持久层,浏览器需要在硬盘中保存类似cookie的各种数据,HTML5定义了web
database技术,这是一种轻量级完整的客户端存储技术。
浏览器主要组件(如图):
三、渲染引擎
渲染引擎的职责就是渲染,即在浏览器窗口中显示所请求的内容。
默认情况下,渲染引擎可以显示html、xml文档及图片,它也可以借助插件(一种浏览器扩展)显示其他类型数据,例如使用PDF阅读器插件,可以显示PDF格式,将由专门一章讲解插件及扩展,这里只讨论渲染引擎最主要的用途——显示应用了CSS之后的html及图片。
渲染引擎简介:
Firefox、Chrome和Safari是基于两种渲染引擎构建的,Firefox使用Geoko——Mozilla自主研发的渲染引擎,Safari和Chrome都使用webkit。
渲染主流程:
渲染引擎首先通过网络获得所请求文档的内容,通常以8K分块的方式完成。
下面是渲染引擎在取得内容之后的基本流程:
解析html以构建dom树 -> 构建render树 -> 布局render树 -> 绘制render树
渲染引擎开始解析html,并将标签转化为内容树中的dom节点。接着,它解析外部CSS文件及style标签中的样式信息。这些样式信息以及html
中的可见性指令将被用来构建另一棵树——render树。
Render树由一些包含有颜色和大小等属性的矩形组成,它们将被按照正确的顺序显示到屏幕上。
Render树构建好了之后,将会执行布局过程,它将确定每个节点在屏幕上的确切坐标。再下一步就是绘制,即遍历render树,并使用UI后端层绘制每个节点。
值得注意的是,这个过程是逐步完成的,为了更好的用户体验,渲染引擎将会尽可能早的将内容呈现到屏幕上,并不会等到所有的html都解析完成之后再去构建和布局
render树。它是解析完一部分内容就显示一部分内容,同时,可能还在通过网络下载其余内容。
从图3和4中可以看出,尽管webkit和Gecko使用的术语稍有不同,他们的主要流程基本相同。Gecko称可见的格式化元素组成的树为frame
树,每个元素都是一个frame,webkit则使用render树这个名词来命名由渲染对象组成的树。Webkit中元素的定位称为布局,而Gecko中称为回流。
Webkit称利用dom节点及样式信息去构建render树的过程为attachment,Gecko在html和dom
树之间附加了一层,这层称为内容接收器,相当制造dom元素的工厂。下面将讨论流程中的各个阶段。
四、解析
既然解析是渲染引擎中一个非常重要的过程,我们将稍微深入的研究它。首先简要介绍一下解析。
解析一个文档即将其转换为具有一定意义的结构——编码可以理解和使用的东西。解析的结果通常是表达文档结构的节点树,称为解析树或语法树。
文法(Grammars)
解析基于文档依据的语法规则——文档的语言或格式。每种可被解析的格式必须具有由词汇及语法规则组成的特定的文法,称为上下文无关文法。人类语言不具有这一特性,因此不能被一般的解析技术所解析。
解析器-词法分析器(Parser-Lexer combination)
解析可以分为两个子过程——语法分析及词法分析
词法分析就是将输入分解为符号,符号是语言的词汇表——基本有效单元的集合。对于人类语言来说,它相当于我们字典中出现的所有单词。
语法分析指对语言应用语法规则。
解析器一般将工作分配给两个组件——词法分析器(有时也叫分词器)负责将输入分解为合法的符号,解析器则根据语言的语法规则分析文档结构,从而构建解析树,词法分析器知道怎么跳过空白和换行之类的无关字符。
解析过程是迭代的,解析器从词法分析器处取到一个新的符号,并试着用这个符号匹配一条语法规则,如果匹配了一条规则,这个符号对应的节点将被添加到解析树上,然后解析器请求另一个符号。如果没有匹配到规则,解析器将在内部保存该符号,并从词法分析器取下一个符号,直到所有内部保存的符号能够匹配一项语法规则。如果最终没有找到匹配的规则,解析器将抛出一个异常,这意味着文档无效或是包含语法错误。
转换(Translation)
很多时候,解析树并不是最终结果。解析一般在转换中使用——将输入文档转换为另一种格式。编译就是个例子,编译器在将一段源码编译为机器码的时候,先将源码解析为解析树,然后将该树转换为一个机器码文档。
解析器类型(Types of parsers)
有两种基本的解析器——自顶向下解析及自底向上解析。比较直观的解释是,自顶向下解析,查看语法的最高层结构并试着匹配其中一个;自底向上解析则从输入开始,逐步将其转换为语法规则,从底层规则开始直到匹配高层规则。
自底向上解析会扫描输入直到匹配了一条规则,然后用该规则取代匹配的输入,直到解析完所有输入。部分匹配的表达式被放置在解析堆栈中。
自底向上解析器称为shift reduce解析器,因为输入向右移动(想象一个指针首先指向输入开始处,并向右移动),并逐渐简化为语法规则。
自动化解析(Generating parsers automatically)
解析器生成器这个工具可以自动生成解析器,只需要指定语言的文法——词汇表及语法规则,它就可以生成一个解析器。创建一个解析器需要对解析有深入的理解,而且手动的创建一个由较好性能的解析器并不容易,所以解析生成器很有用。
Webkit使用两个知名的解析生成器——用于创建语法分析器的Flex及创建解析器的Bison(你可能接触过Lex和Yacc)。Flex
的输入是一个包含了符号定义的正则表达式,Bison的输入是用BNF格式表示的语法规则。
HTML解析器(HTML Parser)
HTML解析器的工作是将html标识解析为解析树。
HTML文法定义(The HTML grammar definition)
W3C组织制定规范定义了HTML的词汇表和语法。
非上下文无关文法(Not a context free grammar)
正如在解析简介中提到的,上下文无关文法的语法可以用类似BNF的格式来定义。
不幸的是,所有的传统解析方式都不适用于html(当然我提出它们并不只是因为好玩,它们将用来解析css和js),html
不能简单的用解析所需的上下文无关文法来定义。
Html有一个正式的格式定义——DTD(Document Type Definition文档类型定义)——但它并不是上下文无关文法,html更接近于xml
,现在有很多可用的xml解析器,html有个xml的变体——xhtml,它们间的不同在于,html
更宽容,它允许忽略一些特定标签,有时可以省略开始或结束标签。总的来说,它是一种soft语法,不像xml呆板、固执。
显然,这个看起来很小的差异却带来了很大的不同。一方面,这是html流行的原因——它的宽容使web
开发人员的工作更加轻松,但另一方面,这也使很难去写一个格式化的文法。所以,html的解析并不简单,它既不能用传统的解析器解析,也不能用xml解析器解析。
HTML DTD
Html适用DTD格式进行定义,这一格式是用于定义SGML家族的语言,包括了对所有允许元素及它们的属性和层次关系的定义。正如前面提到的,html DTD
并没有生成一种上下文无关文法。
DTD有一些变种,标准模式只遵守规范,而其他模式则包含了对浏览器过去所使用标签的支持,这么做是为了兼容以前内容。最新的标准DTD在
DOM
输出的树,也就是解析树,是由DOM元素及属性节点组成的。DOM是文档对象模型的缩写,它是html文档的对象表示,作为html元素的外部接口供js等调用。
树的根是“document”对象。
热门工具 换一换