6月阅读周·WebKit技术内幕 | 浏览器内核及特性
背景
去年下半年,我在微信书架里加入了许多技术书籍,各种类别的都有,断断续续的读了一部分。
没有计划的阅读,收效甚微。
新年伊始,我准备尝试一下其他方式,比如阅读周。每月抽出1~2个非连续周,完整阅读一本书籍。
这个“玩法”虽然常见且板正,但是有效,已经坚持阅读五个月。
已读完书籍:《架构简洁之道》、《深入浅出的Node.js》、《你不知道的JavaScript(上卷)》、《你不知道的JavaScript(中卷)》、《你不知道的JavaScript(下卷)》、《数据结构与算法JavaScript描述》。
当前阅读周书籍:《WebKit技术内幕》。
浏览器内核及特性
内核和主流内核
在浏览器中,有一个最重要的模块,它主要的作用是将页面转变成可视化(准确讲还要加上可听化)的图像结果,这就是浏览器内核。通常,它也被称为渲染引擎。所谓的渲染,就是根据描述或者定义构建数学模型,通过模型生成图像的过程。浏览器的渲染引擎就是能够将HTML/CSS/JavaScript文本及其相应的资源文件转换成图像结果的模块。
目前,主流的渲染引擎包括Trident、Gecko和WebKit,它们分别是IE、火狐和Chrome的内核。同一个渲染引擎(虽然可能有很多不同的变化)可以被多个浏览器所采用。
使用Linux内核的操作系统非常多,但是它们都是基于Linux内核。但是,某些操作系统对内核作了很多的改变,这使得这些操作系统之间差别也很大。
自从开放源代码后,越来越多的浏览器采用该渲染引擎,特别是在移动领域,更占据了垄断的地位。根据Wikipedia上面的数据,超过30种浏览器和Web平台是基于WebKit渲染引擎开发的。值得强调的是,现在已经有了基于WebKit开发的Web平台,包括ChromeOS和WebOS。它们利用HTML5强大的能力,具有前瞻性地尝试开发了支持HTML5的Web操作系统。
内核特征
根据渲染引擎所提供的渲染网页的功能,一般而言,它需要包含如图2所描述的众多功能模块。图中主要分成三层,最上层使用虚线框住的是渲染引擎所提供的功能。
从图中大致可以看出,一个渲染引擎主要包括HTML解释器、CSS解释器、布局和JavaScript引擎等,其他还有绘图模块、网络等并没有在图中直接表示出来,下面依次来描述它们:
- HTML解释器:解释HTML文本的解释器,主要作用是将HTML文本解释成DOM(文档对象模型)树,DOM是一种文档的表示方法。
- CSS解释器:级联样式表的解释器,它的作用是为DOM中的各个元素对象计算出样式信息,从而为计算最后网页的布局提供基础设施。
- 布局:在DOM创建之后,Webkit需要将其中的元素对象同样式信息结合起来,计算它们的大小位置等布局信息,形成一个能够表示这所有信息的内部表示模型。
- JavaScript引擎:使用JavaScript代码可以修改网页的内容,也能修改CSS的信息,JavaScript引擎能够解释JavaScript代码并通过DOM接口和CSSOM接口来修改网页内容和样式信息,从而改变渲染的结果。· 绘图:使用图形库将布局计算后的各个网页的节点绘制成图像结果。
- 绘图:使用图形库将布局计算后的各个网页的节点绘制成图像结果。
这些模块依赖很多其他的基础模块,这其中包括网络、存储、2D/3D图形、音频视频和图片解码器等。实际上,渲染引擎中还应该包括如何使用这些依赖模块的部分,这部分的工作其实并不少,因为需要使用设计出合适的框架使用它们来高效地渲染网页,后面章节会详细介绍。例如,利用2D/3D图形库来实现高性能的网页绘制和网页的3D渲染,这个实现非常的复杂。最后,当然,在最下层,依然少不了操作系统的支持,例如线程支持、文件支持等。
在了解了这些主要模块之后,下面介绍这些模块是如何一起工作以完成网页的渲染过程。一般的,一个典型的渲染过程如图3所示,这是渲染引擎的核心过程,一切都是围绕着它来的。
下面从左至右逐次解释图3中的这一过程,先后关系由图中的实线箭头表示。从左上角开始,首先是网页内容,输入到HTML解释器,HTML解释器在解释它后构建成一棵DOM树,这期间如果遇到JavaScript代码则交给JavaScript引擎去处理;如果网页中包含CSS,则交给CSS解释器去解释。当DOM建立的时候,渲染引擎接收来自CSS解释器的样式信息,构建一个新的内部绘图模型。该模型由布局模块计算模型内部各个元素的位置和大小信息,最后由绘图模块完成从该模型到图像的绘制。
最后解释图3中虚线箭头的指向含义。它们表示在渲染过程中,每个阶段可能使用到的其他模块。在网页内容的下载中,需要使用到网络和存储,这点显而易见。但计算布局和绘图的时候,需要使用2D/3D的图形模块,同时因为要生成最后的可视化结果,这时需要开始解码音频、视频和图片,同其他内容一起绘制到最后的图像中。
在渲染完成之后,用户可能需要跟渲染的结果进行交互,或者网页自身有动画操作,一般而言,这需要持续的重复渲染过程。
WebKit内核
“WebKit”其实可以表示两种含义,这里姑且称为广义WebKit和狭义WebKit。广义的WebKit指的就是WebKit项目。为了解释狭义WebKit,让我们在一个更高层次上俯视一下这个开源项目。以后如无特别说明,所引用的WebKit均是指广义的概念。
WebKit项目自开源以来就以结构清晰、易于维护等优点受到了众多浏览器或者Web平台厂商的青睐。随之而来一个显而易见的问题就是,由于各自需求不同,或者操作系统不同,或者依赖的模块不同(如2D图形库,有CG、skia、cairo、Qt等),操作系统的开发者必然需要WebKit设计和定义一套灵活的框架结构,而不同的厂商基于框架结构,完成基于自身操作系统和依赖模块的实现,这里我们也称之为WebKit移植(Port)。WebKit这种简单灵活和便于引入新移植的特性,使其迅速成为最受欢迎的渲染引擎。基于WebKit的浏览器遍地开花,不仅包括桌面市场,也包括逐步崛起的移动市场。从渲染引擎市场的追随者到领跑者,WebKit仅仅用了不到10年的时间,这不得不说是个奇迹。
WebKit有众多的移植,每个移植的实现都不同,出于自身的考虑,每个移植对HTML5规范的支持也不尽相同,所以,尽管都使用WebKit,但还是可能对兼容性带来很大的挑战。
WebKit和WebKit2
这里说的WebKit不是指开源项目WebKit,而是前面说到的狭义上的绑定和接口层。同样的,WebKit2也是一个狭义上的绑定和接口层。但是,WebKit2不是WebKit绑定和接口层的简单修改版,而是一组支持新架构的全新绑定和接口层。在Chromium项目中,为了网页浏览环境的安全性和稳定性原因考虑而引入了跨进程的架构后,WebKit开源项目也一直希望加入这方面的支持。可惜,这个特性一直没有被加入到WebKit项目中来。
在2010年4月,苹果宣布了WebKit2,目标就是抽象出一组新的编程接口,该接口和调用者代码与网页的渲染工作代码不在同一个进程,这显然有了Chromium多进程的优点,但是与此同时,WebKit2接口的使用者不需要理解和接触背后的多进程和进程间通信等复杂机制,WebKit2部分代码也属于WebKit项目。
Chromium内核:Blink
历史总是惊人的相似,当年发生在KHTML项目上的事情也同样发生在WebKit项目上。2013年4月(又是4月),Google宣布了从WebKit复制出来并独立运作的Blink项目,其中的原因也是一言难尽,主要还是Google和苹果公司有了一些分歧。最初,Blink和WebKit没有特别大的不同,因为刚刚从WebKit复制过来。
在二者“分手”后,WebKit将与Google Chromium浏览器相关的代码移除,同时,Blink将除Chromium浏览器需要之外的其他移植的代码都删除了。不过,可以预见的是,二者以后的差别肯定会越来越大,这是因为Google希望未来在Blink中加入很多新的技术,下面是Chromium网站上列出的:
- 其一,实现跨进程的iframe。iframe允许网页中嵌入其他页面,这存在潜在的安全问题。一个新的想法就是为iframe创建一个单独的沙箱进程。该部分的介绍在第12章展开。
- 其二,重新整理和修改WebKit关于网络方面的架构和接口。长期以来,WebKit中的一些实现是以Mac OS平台为基础的,所以存在某些方面的限制,Blink将会在这方面做比较大的调整。
- 其三,一个更为胆大更为激进的想法就是将DOM树引入JavaScript引擎中。由前面的介绍可以看到,目前DOM和JavaScript引擎是分开的,这意味着JavaScript引擎访问DOM树需要较高的代价。笔者认为这是一个大胆而又具有革命性的尝试,会带来性能的极大提升,为什么呢?原因是JavaScript引擎访问DOM树需要额外的负担,这影响了访问速度。
- 其四,就是针对各种技术的性能优化,包括但是不限于图形、JavaScript引擎、内存使用、编译的二进制文件大小等。
总结
本篇作为开始,主要介绍WebKit内核的特征分析和框架阐述。
作者介绍
非职业「传道授业解惑」的开发者叶一一。
《趣学前端》、《CSS畅想》等系列作者。华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞👍 | 收藏⭐️ | 留言📝。
- 点赞
- 收藏
- 关注作者
评论(0)