浏览器工作原理

浏览器工作原理

浏览器作为一个客服端,它的主要作用就是展示可访问的资源,不管这些资源是本地资源还是通过网络请求获取到的资源

历史

我学习一个东西喜欢看他的历史,这样才能对它诞生的原因以及发展有一定了解,才能知道某个技术点或功能出现是目的是什么。

我们都知道,互联网实现了数据的共享,当越来越多的人进入了互联网。如何去‘共享’呢?展示方式是什么呢?如果去管理更多的资源呢?这些问题迫在眉睫。

  • 1990年,伯纳斯-李制作了第一个万维网浏览器和网页服务器。实现了他的《关于信息化管理的建议》的数据管理模型。允许用户在一台计算机上通过internet存取另一台计算机的信息。主要以超文本的展示内容。这就有了如何去共享以及展示方式和管理方式的开端。
  • 随后,各大浏览器开发商开始开发属于自己的浏览器,各自争夺市场。在没有开源的年代,浏览器的运行就是一个黑盒,开发人员不知道他的原理是什么,只知道他能做什么。随着时代的发展,从单纯的超文本展示变得更加丰富。不管是音频、视频还是其他格式的文件。那么这就要求浏览器需要有处理各种资源的能力。
  • 发展到今天,占领大部分市场的有五大浏览器 Chrome(google)、IE(microsoft)、Firefox(mozilla)、Opera(Opera Software ASA)、Safari(Apple)。

主要构成

虽然浏览器开发商们有没有什么所谓的标准,但是在大致结构上面他们还是很有默契的,当然也有自己独有的功能。

我们主要以chrome,Firefox和Safari开源或部分开源的浏览器作为例子。

浏览器作为一个客户端,也是使用最广的一款软件,主要使用c++代码编写,他的主要构成:

  1. 用户界面:包括地址栏、后退/前进按钮、书签目录、刷新按钮等。也就是除了显示请求内容的主窗口之外的部分。
  2. 浏览器引擎:用来查询和操作渲染引擎的接口。
  3. 渲染引擎(呈现引擎):用来处理资源内容,并显示处理结果,也就是我们所说的内核。
  4. 网络:完成网络调用。
  5. UI后端 : 底层使用操作系统的用户接口,具有不特定平台的通用接口。
  6. js解析器 : 解释执行js脚本。
  7. 数据存储 : 占用一定的硬盘实现数据的存储。

组成结构示意图
浏览器工作原理_第1张图片
主要浏览器 和内核的对应关系

浏览器名称 渲染引擎(内核) ECMAScript引擎(JS引擎)
IE6-8 Trident JScript(ie3-8)、Chakra(ie9)
Firefox 3.5+ Gecko TraceMonkey
Chrome4+ WebKit V8
Safari4+ WebKit SquirrelFish Extreme
Opera10+ Presto Carakan

Firefox使用的是Gecko,是Mozila自主研发的渲染引擎。Safari和Chrome都是用的webkit,webkit是开源的渲染引擎,由Linux平台研发 http://webkit.org。

简单流程

当我们从浏览器地址栏中输入一个域名地址,触发网络请求,网络层得到响应以后,渲染引擎会从网络层中获取请求回来的文档内容,内容大小有一定限制。渲染引擎开始解析请求回来的资源,最后把解析之后的内容结合UI后台,通过调用操作系统的api绘制我们的主要内容,此时操作系统的api则会根据硬件的不同绘制出不同的效果。

逐步分析

  • 渲染引擎(呈现引擎)
  1. 基本功能
    渲染引擎即内核,浏览器核心的部分,负责解析和呈现资源。浏览器能解析什么样的资源取决于内核能解析什么样的资源。默认情况下,渲染引擎可以显示html、xml文档和图片。如果要解析其他资源可以借助扩展插件或者第三方插件。浏览器呈现什么样的样式取决于渲染引擎渲染成什么样的页面格式,不同浏览器因为内核不同,展现出来的页面格式不同。所以我们平时做样式的兼容是根据内核的不同去区分浏览器的。而JS语法的支持程度和运行速度是根据JS解析引擎去控制。
  2. 基本流程
    以解析html为例(最常见的文件),首先将文档内容转换为DOM树节点。同时解析CSS映射成为CSSOM用于构建呈现树。呈现树构建好以后会布局每个节点的坐标。布局好确切坐标以后开始遍历渲染树,根据UI后台绘制每个节点。呈现给用户。

webkit工作流程图
浏览器工作原理_第2张图片
Geoko工作流程图
浏览器工作原理_第3张图片

值得注意的是,渲染引擎解析的过程是逐步完成的,并不会等到所有的html都解析完以后再去布局Render树,解析一部分内容就显示一部分内容,以增加用户体验。

  1. DOM树构建和解析
    如图所示,在DOM树构建以前不管是Webkit还是Geoko,都有解析这个过程。当拿到一个html文件,根据词汇和语法规则从上到下解析,把html对应解析为语法树。所以我们在编写html的时候,最开始就需要告诉解析器,我们这个文档的类型(DOCTYPE)是什么,他才知道按照什么样的语法规则去解析。值得注意的是,html解析器只会将html标识解析为语法树(由w3c制定的标识规范,语法树概念自查),语法树生成以后会映射成为DOM树,映射为对应的DOM元素以及属性节点,这时就有了我们的DOM对象,并且提供了相关的DOM接口给脚本语言调用。所以最后我们得到的DOM树就是以根为Document的对象,并与标签建立一一对应的树状关系。
    那DOM树构建是从何时开始呢?
    从接收到文档开始进行转码,同时把转码后的标记构建成DOM树,这两个过程就是标记化和树构建。同样的DOM标准也是w3c制定(http://www.w3.org/DOM/DOMTR)。解析的具体算法不做深入讨论,可以在对应的规范文档中查看具体的算法详情。
    另外提一点,如果你同时在学习DOM的api,你需要知道DOM树构建和遍历节点的规则。我们都知道DOM树的构建是逐个节点去构建的,他遍历也是逐个节点去遍历的,并且是深度遍历,即要等到该节点以及其后代节点全部遍历完成才会去遍历他的同级节点。生成DOM树的时候遍历生成完最后一个节点,DOM树构建完成,然后才会触发domcontentloaded事件。

  2. css解析
    在构建DOM树的时候遇到js和css元素,html解析器就会将控制器转让给js解析器或者css解析器,去构建CSSOM。CSS的规范同样是w3c制定的。从图中我们可以看到,有专门的css解析器。因浏览器内核而异,使用的css解析器也有差异。css解析器按照自己的规则解析成Stylesheet对象。外部css的引入并不会让文档停止解析,包括图片的引入,都是并发进行的,因为样式并不会改变DOM树的结构。

  3. 脚本解析
    在遇到脚本时文档将停止解析,直到脚本执行完成。如果脚本是外部的,会等到资源获取完成以后才会继续解析。同时,在外部脚本引入的标签中,有‘defer’去标记此脚本时同步引入还是异步引入,以此作为文档是否停止解析的依据。如果为异步,浏览器则会新建立一个线程去解析文档。如果此时脚本有对DOM更改的操作,会再次让DOM重新构建。同时我们需要知道另外一个件事情,现代浏览器js的运行并不是渲染引擎所做的事情,而是有专门的js引擎,上表有列出各大浏览器对应的js解析引擎,其中V8是运行速度最快的js引擎。

  4. 呈现树构建
    DOM树构建完之后,浏览器把DOM树中的一些不可视元素去掉,然后与CSSOM合成一棵呈现树,呈现树在不同内核的浏览器中叫法不一样,webkit中叫Render tree,Geoko中交Frame tree,但是最终结果是一样的。由可视化元素按照顺序组成的树,也是HTML文档的可视化表现形式,通过用户界面的基础组件绘制。在DOM树构建的同时,渲染树也在构建,并不是等到DOM树构建完成以后再去构建渲染树的。我们知道,在css样式中,某些属性会导致呈现结构的改变,例如:display:none。这类的节点不会构建到呈现树中,因此在呈现树中都有与之对应的DOM树节点,但是在DOM树中,不一定有与之对应的呈现树节点。我们通过api去获取DOM节点的时候,哪怕是display:none的节点。我们也能获取的到。因为它对应的DOM节点对应已经构建好了。

  5. Layout(布局)&Reflow(回流)
    有了呈现树以后,渲染引擎已经知道网页中有哪些节点以及各个节点的CSS定义和他们的从属关系,则开始计算他们在屏幕之中的位置(css的定位等属性)。这个过程在webkit中叫layout布局,在Geoko中叫reflow回流。这也涉及到了我们平时所说的回流,一个页面的呈现必定会引起一次回流和重绘,就是在第一次构建呈现树的时候。

  6. Painting(绘制)
    从上面的图中,我们可以看到,不同内核的实现差异就在DOM到Layout或者说Reflow的过程中。前面的步骤完成以后,渲染引擎知道哪些节点显示的位置和节点的css属性,按照计算出来的规则,通过UI后台,根据显卡等硬件把内容显示到浏览器主窗口上。
    所以我们在说回流的时候必定会引擎重新绘制。当然其他的操作,如果改变了DOM结构、CSSOM结构、呈现树结构的都会引起一次回流和重绘。除了这些原因以外,图片下载完成后,需要对布局进行更改,也会引起一次重绘,因为图片是在绘制阶段去渲染的(图片的加载会在浏览器资源文章分享)。

简单的说一下整个过程:

  1. 地址栏输入地址触发网络请求,获取到html文件。
  2. HTML解析器解析HTML文件构建成为DOM树。
  3. 遇到CSS通过CSS解析器解析成为CSSOM。
  4. 遇到JS通过JS解析器解析。
  5. DOM Tree和CSSOM构建呈现树(6、7两个步骤)。
  6. 呈现树根据结构样式确定节点的位置(布局或者回流) ----回流。
  7. 确定好位置以后,根据外观样式绘制 ----重绘。
  8. 通过UI后台和用户界面组件把内容显示到浏览器主窗口上。

浏览器工作原理_第4张图片

误区

在我最开始学习的时候一直对整过过程的理解有一个 误区,认为回流是改变DOM tree的过程,重绘是改变呈现树的过程。没有仔细去看它的实现过程,希望后面学习的人不再有这个想法。

你可能感兴趣的:(web)