6月阅读周·WebKit技术内幕 | WebKit架构和模块
背景
去年下半年,我在微信书架里加入了许多技术书籍,各种类别的都有,断断续续的读了一部分。
没有计划的阅读,收效甚微。
新年伊始,我准备尝试一下其他方式,比如阅读周。每月抽出1~2个非连续周,完整阅读一本书籍。
这个“玩法”虽然常见且板正,但是有效,已经坚持阅读五个月。
已读完书籍:《架构简洁之道》、《深入浅出的Node.js》、《你不知道的JavaScript(上卷)》、《你不知道的JavaScript(中卷)》、《你不知道的JavaScript(下卷)》、《数据结构与算法JavaScript描述》。
当前阅读周书籍:《WebKit技术内幕》。
WebKit架构和模块
WebKit架构
WebKit的一个显著特征就是它支持不同的浏览器,因为不同浏览器的需求不同,所以在WebKit中,一些代码可以共享,但是另外一部分是不同的,这些不同的部分称为WebKit的移植(Ports)。
图中的WebKit架构,虚线框表示该部分模块在不同浏览器使用的WebKit内核中的实现是不一样的,也就是它们不是普遍共享的。用实线框标记的模块表示它们基本上是共享的,话之所以没有说绝,是因为它们中的一些特性可能并不是共享的,而且可以通过不同的编译配置改变它们的行为。这里面有这么多的不同,所以,很多使用WebKit的浏览器可能会表现出不同的行为,显然就不令人惊奇了。
基于Blink的Chromium浏览器结构
Chromium也是基于WebKit(Blink)的,而且在WebKit的移植部分中,Chromium也做了很多有趣的事情,所以通过Chromium可以了解如何基于WebKit构建浏览器。另一方面,Chromium也是很多新技术的创新者,它将很多先进的理念引入到浏览器领域。
架构和模块
Blink只是其中的一块,和它并列的还有众多的Chromium模块,包括GPU/CommandBuffer(硬件加速架构)、V8 JavaScript引擎、沙箱模型、CC(Chromium Compositor)、IPC、UI等。
“Content模块”和“Content API(接口)”,它们是Chromium对渲染网页功能的抽象。“Content”的本意是指网页的内容,这里是指用来渲染网页内容的模块。浏览器的开发者也可以在WebKit的Chromium移植上渲染网页内容,但是却没有办法获得沙箱模型、跨进程的GPU硬件加速机制、众多的HTML5功能,因为这些功能很多是在Content层里实现的。
“Content模块”和“Content API”将下面的渲染机制、安全机制和插件机制等隐藏起来,提供一个接口层。该接口目前被上层模块或者其他项目使用,内部调用者包括Chromium浏览器、Content Shell等,外部包括CEF(Chromium Embedded Framework)、Opera浏览器等。
“Chromium浏览器”和“Content Shell”是构建在Content API之上的两个“浏览器”,Chromium具有浏览器完整的功能,也就是我们编译出来能看到的浏览器式样。而“Content Shell”是使用Content API来包装的一层简单的“壳”,但是它也是一个简单的“浏览器”,用户可以使用Content模块来渲染和显示网页内容。Content Shell的作用很明显,其一可以用来测试Content模块很多功能的正确性,例如渲染、硬件加速等;其二是一个参考,可以被很多外部的项目参考来开发基于“Content API”的浏览器或者各种类型的项目。
在Android系统上,Content Shell的作用更大,这是因为同它并排的左侧的“Chromium浏览器”部分的代码根本就没有开源,这直接导致开发者只能依赖Content Shell。
多进程模型
很多现代浏览器支持多进程模型,这个模型可以很好地避免上面的问题,虽然它很复杂而且也有自身的问题,例如更多的资源消耗,但是它的优势也是非常明显的。在WebKit内核之上,Chromium率先在WebKit之外引入了多进程模型。
Chromium浏览器主要包括以下进程类型:
- Browser进程:浏览器的主进程,负责浏览器界面的显示、各个页面的管理,是所有其他类型进程的祖先,负责它们的创建和销毁等工作,它有且仅有一个。
- Renderer进程:网页的渲染进程,负责页面的渲染工作,Blink/WebKit的渲染工作主要在这个进程中完成,可能有多个,但是Renderer进程的数量是否同用户打开的网页数量一致呢?答案是不一定。Chromium设计了灵活的机制,允许用户配置,随后就作介绍。此外,在沙箱模型启动的情况下,该进程可能会发生一些改变。
- NPAPI插件进程:该进程是为NPAPI类型的插件而创建的。其创建的基本原则是每种类型的插件只会被创建一次,而且仅当使用时才被创建。当有多个网页需要使用同一种类型的插件的时候,例如很多网页需要使用Flash插件,Flash插件的进程会为每个使用者创建一个实例,所以插件进程是被共享的。
- GPU进程:最多只有一个,当且仅当GPU硬件加速打开的时候才会被创建,主要用于对3D图形加速调用的实现。
- Pepper插件进程:同NPAPI插件进程,不同的是为Pepper插件而创建的进程。
- 其他类型的进程:图中还有一些其他类型的进程没有描述出来,例如Linux下的“Zygote”进程,Renderer进程其实都是由它创建而来。另外一个就是名为“Sandbox”的准备进程。
WebKit2
WebKit2架构及模块
WebKit2是一套全新的结构和接口,而不是一个简单的升级版。它的主要目的和思想同Chromium类似,就是将渲染过程放在单独的进程中来完成,独立于用户界面。
WebKit2中也引入了插件进程,而且它还引入了网络进程。图中的“Web进程”对应于Chromium中的Renderer进程,主要是渲染网页。在这之上的是“UI进程”,它对应于Chromium中的Browser进程。接口就暴露在该进程中,应用程序只需调用该接口即可。其中“应用程序”指的是浏览器或者任何使用该接口的程序。
比较WebKit2和Chromium的多进程模型以及接口
首先,Chromium使用的仍然是WebKit接口,而不是WebKit2接口,也就是说Chromium是在WebKit接口之上构建的多进程架构。
其次,WebKit2的接口希望尽量将多进程结构隐藏起来,这样可以让应用程序不必纠缠于内部的细节,例如邮件客户端等。但是,对Chromium来说,它的主要目的是给Chromium提供Content接口以便构建浏览器,其本身目标不是提供嵌入式接口,虽然有CEF项目基于它构建了嵌入式接口。
最后,Chromium中每个进程都是从相同的二进制可执行文件启动,而基于WebKit2的进程则未必如此,这当然也跟二者的设计理念不同有关。
总结
本篇正式进入介绍WebKit的内部原理部分。基于WebKit的Chromium浏览器的内部结构和模块,并介绍多线程和多进程模型,并将Chromium的多进程模型同WebKit2的多进程模型进行比较,剖析目前前沿的浏览器架构和设计理念。
作者介绍
非职业「传道授业解惑」的开发者叶一一。
《趣学前端》、《CSS畅想》等系列作者。华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞👍 | 收藏⭐️ | 留言📝。
- 点赞
- 收藏
- 关注作者
评论(0)