进击的前端

Quantum聚焦:什么是浏览器引擎?

May 17, 2017

原文地址

2016年10月的时候我们宣布了Quantum项目—我们计划开发下一代浏览器引擎。现在该项目正在顺利进行。事实上我们已经将Quantum项目的阶段性成果应用到了Firefox 53中。

但是,我们意识到对于不开发浏览器的人(其实是大多数人)来说,要理解我们做的一些改变为什么对Firefox如此重要是很困难的。毕竟我们做的大多数改变对用户来说是不可见的。

考虑到这一点,我们开始撰写一系列的博客文章,使大家对我们在Quantum项目中所做的事情有一个更深层的理解。我们希望这一系列的文章能够让你们更好地理解Firefox是如何工作的,同时了解Firefox采用的方式是构建下一代浏览器引擎以更好地利用现代计算机硬件。

作为这一系列文章的开始,我们认为解释Quantum正在改变的基础原理是最合适的。

什么是浏览器引擎,它是怎么工作?

那么要从哪里开始呢?我们认为应该从头开始。

浏览器就是一个软件,它的功能是加载文件(通常从远程服务器)并且在本地显示出来,允许用户和页面交互。

Quantum是我们Mozilla正在进行的一个项目,旨在大规模升级Firefox的一部分,这部分的功能就是基于远程文件计算出要呈现给用户的东西。这部分的专业术语叫“浏览器引擎”。如果没有这部分,你所看到的将会是一行行代码,而不是现在所看到的页面。Firefox的浏览器引擎名字叫Gecko。

简单来说,可以把浏览器引擎比喻成一个黑盒子,就像电视盒子,这个黑盒子从网络接收数据然后把数据计算成要显示在屏幕上的图像。今天的问题是:怎么做到的?把数据计算成我们看到的网页经历了哪些步骤?

黑盒子

组成一个网页的数据包含很多东西,但是基本上可以分解成3个部分:

  • 表示网页结构的代码
  • 提供样式的代码:网页结构的视觉外观
  • 浏览器行为的脚本代码:对用户的行为进行计算并作出反馈,对网页的结构和样式作出改变

浏览器引擎把结构和样式结合在一起,用来绘制显示在屏幕上的网页,并且计算出哪些部分是可以进行交互的。

这一切都始于结构。当你要求浏览器加载一个网站,你会给它一个地址。这个地址对应的是另一台电脑,这台电脑收到请求就会发送数据给你的浏览器。发送数据给浏览器的细节在另一篇文章做了详述。总之最后浏览器拿到了数据。数据以HTML的格式返回,用于描述网页的结构。浏览器又是怎么理解HTML的呢?

浏览器引擎包含了一系列特殊的代码,叫做解析器,它可以把浏览器存在内存中的数据从一种格式转换成另一种格式。HTML解析器专门负责解析HTML数据,例如:

<section>
 <h1 class="main-title">Hello!</h1>
 <img src="http://example.com/image.png">
</section>

解析过程描述如下:

好的,这是个section。包含在section里面的有一个个h1的标题,
标题的内容为'Hello!';还有一张图片也包含在section里面,图片
的数据源为'http://example.com/image.png'。

内存中的网页结构叫做文档对象模型或者DOM。和一长串的文字形式相反,DOM表示为最终网页的元素组成的一棵树:元素包含哪些属性,哪些元素包含在其他元素中。

DOM

除了描述页面的结构,HTML里面也包含了样式和脚本的资源地址。当浏览器找到这些地址,就会去请求对应的地址并加载对应的数据。然后这些数据被传给专门处理这些数据格式的解析器。如果脚本被找到了,在HTML解析完成之前,这些脚本可以改变页面的结构和样式。作为样式格式,CSS在浏览器引擎中扮演下一个角色。

样式

CSS是一种编程语言,开发者可以用这种编程语言去定义页面中特定元素的外观。CSS的全称是”Cascading Style Sheets”(层叠样式表),之所以这样命名,是因为它允许很多样式指令集合,在这些样式指令集中,新的指令可以覆盖旧的或者默认的指令(叫做层叠)。下面是一小段CSS示例:

section {
  font-size: 15px;
  color: #333;
  border: 1px solid blue;
}
h1 {
  font-size: 2em;
}
.main-title {
  font-size: 3em;
}
img {
  width: 100%;
}

CSS被大量分解成被称为规则的组合,这些组合都是由两部分组成。第一部分是选择器。选择器表示DOM中需要更改样式的元素(还记得上面的描述吗?)。另一部分是一个列表,包含着将要应用到选择器对应元素的样式声明列表。浏览器引擎包含了一个子引擎,名字叫样式引擎,它的工作就是将CSS代码指定的样式应用到HTML解析器解析出来的DOM中去。

样式引擎

举例来说,在上面那段CSS代码中,我们声明的一些样式规则,目标选择器是“section”,这个选择器会和DOM中的同名元素匹配。之后样式说明会逐一应用到DOM中的每一个元素。最终DOM中的每一个元素都会被加上样式,我们把这种状态叫做元素的计算样式。当多种样式规则都被应用到同一个元素上的时候,那些排在后面的会覆盖掉排在前面的,定义的样式声明多的会覆盖样式声明少的。可以把样式表想象成临摹用的半透明的薄纸,每一层可以覆盖前面一层,但是同时又能够透过去看到上面一层。

一旦浏览器引擎拿到了计算样式,就会马上用起来。DOM和计算样式都会传给一个布局引擎,这个布局引擎可以计算将要展示页面的窗口的尺寸。布局引擎采用了一系列算法,画一个盒子,然后拿一个元素,把元素的内容以及应用在该元素上的样式依照规则放进盒子里。

布局引擎

布局完成之后要做的就是把页面转换成最终你看到的样子。这个过程被称为渲染,它是所有前面进行的步骤的最终结合。每个被布局定义好的盒子都被绘制好,包括来自DOM的所有内容和来自CSS的所有样式。现在,用户看到了通过对代码重新组装的页面。

以上就是发生的一切。

当用户滚动页面的时候,我们会重绘,然后呈现页面中未被显示在窗口中的新的部分。然而,事实证明用户喜欢滚动!浏览器引擎确信它将会被要求显示初始窗口(我们称为视口)以外的内容。很多现代浏览器深知这一点,因此一开始就会绘制更多的可见内容。当用户滚动的时候,他们想看到的部分其实早已经绘制好并且等着了。结果使滚动变得快速而又平滑。这个技术是合成的基础,一种用于减少页面绘制请求次数的技术手段。

另外,有时候我们需要重绘当前屏幕上的一部分。也许用户正在观看一个60帧每秒的视频。也许页面上有一张幻灯片或者动画列表。浏览器能够检测到到页面的一部分会发生移动或者更新,并且会创建一个控制该部分内容的层,而不是重绘整个页面。一个页面可以有很多层,一层覆盖另一层。其中的某一层可以改变位置,滑动,透明,后置或者前置于另一个不需要重绘任何东西的层。非常方便不是吗?

有时候一个脚本或者一个动画会改变元素的样式。当这个发生的时候,样式引擎需要重新计算这个元素的样式(有可能是页面中更多的元素),重新布局(做一个重排),然后重绘这个页面。这些计算将会花费很多时间,但是只要这种事情只是偶尔发生,那么对用户体验来说不会产生消极的影响。

在现代网页应用中,DOM结构被脚本频繁地改变。这将使整个渲染过程或多或少出现终止并重新开始,同事伴随着HTML被解析到DOM,样式计算,重排和重绘。

渲染过程

标准

不是每一个浏览器都用同样的方式去解析HTML,CSS和JavaScript。不同的浏览器渲染出来的页面可能不同:小到局部样式不同,大到整个网站可能只能在一个浏览器运行而其他浏览器都不行。目前,在现代网络中,大多数网站都能正常运行在你使用的浏览器中,不管你使用的是哪个浏览器。这些浏览器是怎么实现这么高的一致性的呢?

网站代码的格式,和控制代码如何被解析成可见的交互页面的规则,都是被大家都同意的文件定义的,这个文件就叫做标准(规范)。这些标准都是由一个委员会制定,这个委员会由浏览器厂商的代表、web开发者、设计师和这个行业的其他人员组成的。他们一起决定一个浏览器引擎的精确行为:给一段特定的代码,完成对应的展示。这里有HTML,CSS和JavaScript的规范以及图片、视频、音频的数据格式等等。

为什么这个很重要?开发一个全新的浏览器引擎是可行的,只要你确保你的引擎遵循了标准,这个引擎会以和其他所有浏览器一样的方式去为网络上数以十亿计的网页做绘制渲染工作。这意味着让网站正常工作的秘诀不属于任何一个浏览器专属。标准允许用户去选择能满足他们需求的浏览器。

摩尔定律不再

当恐龙漫步在地球上而且人们只有桌面电脑,电脑只会变得更快更强大是一个相对安全的假设。这个想法基于摩尔定律,摩尔定律描述的是一种现象:组件的密度会每两年增加一倍。令人难以置信的是,这个现象在21世纪一直存在,有些人甚至认为,在最新的研究中仍然是正确的。那么为什么在最近的10年里普通电脑的速度趋于平稳?

用户去购买电脑的时候,处理速度不是用户看重的唯一特性。速度快的电脑会非常耗能,发热严重,而且非常贵。有时候,人们需要一款续航很好的电脑。有时候,他们需要一款微型的触控电脑,可以放进裤兜里,而且一整天都不用充电。先进的计算技术使得这个成为可能(令人惊讶!),但是是以原始速度为代价的。就像汽车一样,不可能越快越高效,电脑也是一样的。解决方案就是在一个CPU芯片上集成很多个“电脑”(核心)。一个智能手机拥有4个低性能的核心是很常见的。

不幸的是,浏览器的历史设计对上行速度做了假设。而且,要编写能够同时利用CPU的多核心的代码是很复杂的。如此一来,在这个到处都是小电脑的时代,我们要如何创造一个快速、高效的浏览器呢?

我们有一些想法。

在接下来的几个月里,我们一起来仔细看看Firefox上的一些新的变化,以及Firefox是如何充分利用硬件的优势呈现一个快速稳定的浏览器来点亮网站的吧。

前进!

以上。我第一完整地翻译一篇英文技术文章,文中有诸多生硬拗口甚至难以理解的地方。请看官们帮忙指正,勿喷。


Kyle Mathews

Written by ricosmall.
Github