2.基于 Blink 的 Chrominum 浏览器结构 2.1 Chrominum 浏览器的架构及模块

        Chromium也是基于WebKit(Blink)开发的,并且在WebKit的移植部分中,Chromium也做了很多有趣的事,所以通过Chromium可以了解如何基于WebKit构建浏览器。,更进一步说,chromium也做了很多技术创新,将很多先进的理念引入到浏览器领域。

(1)从架构上看,WebKit(Blink)只是其中的一块,,还包括GPU/CommandBuffer(硬件架构)、V8 JavaScript引擎、沙箱模型、CC(Chromium Compositor)、IPC、UI等。

GPU/Command Buffer ,硬件加速架构Content 模块、Content 接口(API):Chromium 对渲染网页功能的抽象,将下面的渲染、安全、插件机制隐藏起来,提供一个接口层(供上层模块或其他项目使用)。也可以在 WebKit 的 Chromium 移植上渲染网页内容(无法获取 Content 层中实现的沙箱模型、跨进程的 GPU 硬件加速机制等)Content Shell:使用 Content API 来包装的一层简单的壳,用户可以使用 Content 模块来渲染和显示网页内容。作用可以用来测试 Content 模块很多功能的正确性,也可以作为一种外部项目开发的参考Android WebView:利用 Chromium 实现来替换原来 Android 默认的 WebView

          “Content模块”和“Content API(接口)”,是对渲染网页功能的抽象,“Content”的本意是指网页的内容,这里是指用来渲染网页内容的模块。这个渲染与WebKIt(Blink)的渲染功能的区别是,后者没有办法获得沙箱模型、跨进程的GPU硬件加速机制、众多的HTML5功能。因为这些都是在 Content 层里实现的。

      “Content模块”和“Content API”将下面的渲染机制、安全机制和插件机制等隐藏起来,提供一个接口层。该接口层被内部的 Chrominum 浏览器、Content Shell等调用,外部被CEF(Chromium Embedded Framework)、OPera浏览器调用。

        Chrominum 浏览器和 Content Shell 是构建在 Content API之上的两个浏览器。 Chrominum 浏览器是具有完整功能的浏览器;而Content Shell是一个简单的“壳”的浏览器,使用content模块来渲染和显示网页内容,其作用是测试content模块很多如渲染、硬件加速等功能的正确性,另外是一个参考,可以被很多外部项目参考来开发基于“Content API”的浏览器或者各种类型的项目。

        在Andriod系统上,Content Shell的作用更大,因为chromium浏览器的部分代码并没有开源,只能依赖Content Shell。最右边的 Andriod WebView,是为了满足Android系统上的WebView而设计的,其思想是利用Chromium的实现来替换原来的Andriod系统默认的WebView。 (2)多进程模型

        在WebKIt内核之上,Chromium率先引进多进程模型。多进程不可避免带来一些问题和复杂性,但可以带来以下三点好处:

 避免因单个页面的不响应或者崩溃而影响整个浏览器的稳定性,特别是对用户界面的影响。当第三方插件崩溃时,不会影响页面或者浏览器的稳定性,这时因为第三方插件也被使用单独的进程来运行。方便安全模型的实施,也就是说沙箱模型是基于多进程架构的。

        图中给出了Chromium浏览器器常用的多进程模型,因为其架构的灵活性,可以为使用者提供通过简单的设置来随意改变进程的模型方式,图中方框代表进程,连线代表IPC进程间的通信,没有连线的表明不同类型进程之间没有通信,如NPAPI插件和GPU之间就没有通信,这是因为NPAPI是早期的插件标准,它没有定义使用GPU加速的接口。

Browser 进程:浏览器主进程,负责浏览器界面的显示、各个页面的管理,是所有其他类型进程的祖先,负责它们的创建和销毁等工作,有且仅有一个。Renderer 进程:网页的渲染进程,负责页面的渲染工作,Blink/WebKit 的渲染工作主要在这个进程中完成,Renderer 进程数量不一定与用户打开页面的数量一致:且在沙箱模型启动的情况下,该进程可能会发生一些变化。NPAPI 插件进程:该进程是为 NPAPI 类型的插件而创建,原则是每种类型的插件只会创建一次,而且仅当使用时才被创建,有多个网页需要使用同一类型的插件的时候,插件进程会为每个使用者创建一个实例,即插件进程是被共享的。GPU 进程:最多只有一个,当且仅当 GPU 硬件加速打开的时候才会被创建,主要用于对 3D 图形加速调用实现。Pepper 插件进程: 同 NPAPI 插件进程,为 Pepper 插件而创建。其他类型的进程:如 Linux 下的 Zygote 进程(创建 Renderer 进程)、Sandbox 准备进程(安全机制)

Chrominum 多进程模型特征:

Browser 进程和页面的渲染时分开的,页面渲染进程的崩溃不会导致浏览器主界面的崩溃每个网页是独立的进程,这保证了页面之间相互不影响插件进程也是独立的,插件本身的问题不会影响到网页和主界面GPU 硬件加速进程也是独立的,且只有一个 GPU 进程

        而在 Android 平台上,目前版本不支持插件,所以没有插件今年成,GPU 进程演变成 Borwser 进程的一个GPU线程,可以节省资源;Renderer进程会演变成服务(Service)进程。由于 Android 系统的局限性,Rneder 进程的数目会被严格限制,所以移动端浏览器引入了“影子”标签的概念,移动端浏览器会将后台的网页所使用的渲染设施都清除,当用户再次切换回来的时候,网页需要重新加载和渲染

process-per-site-instance:每一个页面都创建一个独立的 Renderer 进程,不管这些页面是否属于同一个域。这样好处是每个页面互相不影响,但是会造成资源的浪费。process-per-site:属于同一个域的页面共享同一个进程,不属于同一个域的页面分属不同的进程,这样的好处是进程可以共享,内存消耗相对小,但是副作用是导致Renderer进程特别大。process-per-tab:chromium的默认行为,无论是不是不同域不同实例,每个标签页都创建一个独立进程(Chromium 默认行为),会造成资源浪费。single process:不为页面创建任何独立的进程,所有渲染工作都在 Browser 进程中的多个线程中进行,这个属于实验性质且稳定性差,只有在比较单进程和多进程对比时才使用。在Andriod WebView中,该模式被采用。  

(3)Browser 进程和 Renderer进程

        Browser进程和Renderer进程都是在WebKit的接口之外由Chromium引入的,其如何利用WebKit渲染网页见下图所示:

        最下面的时WebKit接口层,一般是基于Webkit接口层的浏览器直接在上面构建,而没有引入复杂的多进程机构。

          Webkit 黏附层的出现主要是因为 Chrominum 中的一些类型和 Webkit 内部不一致,所以需要一个简单的桥阶层         Render 进程主要处理进程间通信,接受来自 Browser 进程的请求,并调用相应的 Webkit 接口层。同时,将 Webkit 的处理结果发送回去         在 Browser 进程中,与 Render 进程相应的就是 RenderHost,其目的是处理同 Render 进程之间的通信,用来给 Render 进程发送请求并接收来自 Render 进程的结果

        Web Contents表示是就是网页的内容,网页由多个需要绘制的内容,同时包括显示网页内容的一个子窗口(在桌面系统上),这个子窗口最后被嵌入浏览器的用户界面,作为i它的一个标签页。 (4)多线程模型        每个进程内部都有很多线程,对于 Browser 进程,多线程的目的主要是为了保持用户界面的高度响应,保证 UI(Browser 主线程)线程不会被其他费时的操作阻碍从而影响对用户操作的响应。而在 Render 进程中,Chrominum 则不让其他操作阻止渲染线程的快速运行,为了利用多核的优势,Chromium将渲染过程管线化,这样可以让渲染的不同阶段在不同线程执行。

网页渲染的过程在进程模型中的工作方式如下:

Browser 进程收到用户的请求,首先有 UI 线程处理,而且将相应的任务给 IO 线程,IO 线程随即将该任务传递给 Render 进程Render 进程的 IO 线程经过简单的解释后交给渲染线程。渲染线程接受请求,加载网页并渲染网页,这其中可能需要 Browser 进程获取资源和需要 GPU 进程来帮助渲染。最后 Render 进程将结果由 IO 线程传递给 Browser 进程最后,Browser 进程接收到结果并将结果绘制出来

(5) Content 接口

        Content 接口提供了一层对多进程进行渲染的抽象接口,其目标是要支持所有的 HTML5 功能、GPU 硬件加速功能和沙箱机制,这可以让 Content 接口的使用者们不需要很多的工作即可得到强大的能力         Content 接口的相关代码按照功能分成六个部分,每个部分的接口一般可分成两类,第一类是调用者(Chrominum 浏览器、CEF3和Content Shell等)调用的接口,另一类是调用者应该实现的回调接口,被 Content 接口的内部实现所调用,用来参与具体实现的逻辑或者事件的监听等。

App:这部分主要与应用程序或者进程的创建和初始化相关,它被所有的进程使用,用来处理一些进程的公共操作,具体包括两种类型,第一类主要包括进程创建的初始化函数,也就是Content模块的初始化和关闭动作;第二类主要是各种回调函数,用来告诉嵌入者启动完成,进程启动、退出,沙盒模型初始化开始和结束等。Browser:同样包含两类,第一类包括对一些HTML5功能和其他一些高级功能实现的参与,因为这些实现需要Chromium的不同平台的实现,同时需要如:Notification、Speech recognition、Web worker、Download、Geolocation等这些Content层提供的接口,Content模块需要调用它们来实现HTML5功能。第二类中的典型接口类是ContentBrowserClient,主要是实现部分的逻辑,被Browser进程调用,还有就是一些事件的函数回调。Common:主要定义一些公共接口,这些被Renderer和Browser共享,如一些进程相关、参数、GPU相关等。Plugin:仅有一个接口类,通知嵌入者Plugin进程何时被创建。Renderer:该部分包括两类,第一类包含获取RenderThread的消息循环、注册V8 Extension、计算JavaScript表达式等;第二类包括ContentRendererClient,主要是实现部分逻辑,被Browser端(或者进程)调用,还有就是一些事件的函数回调。Utility:工具类接口,主要包括让嵌入者与Content接口中的线程创建和消息的过滤。

2.2 实践:从Chromium代码结构和运行状态理解现代浏览器

(1)Chrominum Content 接口代码结构         Chromium引入了很多新的特性和功能,除了浏览器外还包括了ChromiumOS和Chrome Frame,这也是新颖的地方。ChromiumOS 就是一个基于Web的操作系统,仅支持Web网页和Web应用程序;Chrome Frame提供一个基于WebKit和Content支持的HTML5的插件。

     在上图中的目录,省略了”third_party“,该目录保存了Chromium所依赖的所有第三方开源项目。因为Chromium提供了很多新的特性和功能,这些功能需要很多库来支持,而且这些特性和功能会存在一些不足或者Chromium有特定的需求,所以,Chromium的做法把超过150个项目包含进来,也就是Blink代码页被包含其中。

      在目录的后面对代码的功能进行了简单的标注说明,都很简明扼要。重点描述的是Content目录。Content的接口主要在”public“目录中,它包含的目录也是按照进程类型来划分的。

(2)Chromium多进程

        通过Chome浏览器和操作系统提供的进程管理工具查看进程情况(略)

(3)Chromium多线程

        通过Chome浏览器和操作系统提供的线程管理工具查看进程情况(略)

好文阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: