webkit渲染过程

本文深入探讨了WebKit的架构,包括WebCore、JavaScriptCore、Port和嵌入式接口,以及Chromium基于Blink的多进程模型。Chromium通过content接口实现了沙箱模型、硬件加速和多进程隔离,提高了浏览器的稳定性和安全性。WebKit2则引入了更多进程分离,以提升安全性与性能。
摘要由CSDN通过智能技术生成

webkit架构和模块

webkit架构

图中虚线框部分表示,该模块部分在不同浏览器对webkit内核的实现不同,也就是说不是普遍共享的。实现框表示,基本上是共享的。(注意,是基本上。他们中的一些特性可能不是共享的,可以通过不同的编译配置改变他们的行为)。

从下往上依次分析:

    • 操作系统:webkit可以在不同的操作系统工作。
    • 众多第三方库:webkit运行的基础。
    • webkit项目

WebCore

WebCore包含了被不同浏览器所使用的共享部分,是渲染加载网页的基础,必不可少。这部分包括,HTML(解释器)、css(解释器)、SVG、DOM、渲染树(renderObject树,renderLayout树)、Inspector(web Inspector,调试网页)等

JavaScriptCore

JavaScriptCore引擎是webkit的默认JavaScript引擎,一些webkit的移植会使用该引擎。事实上,webkit对JavaScript引擎的调用是独立于引擎的。在google的chromium项目中,它就被替换为V8引擎。

webkit Ports

webkit Ports指的是webkit中的非共享部分,对于不同浏览器使用的webkit来说,移植中的这些模块由于平台差异、依赖的第三方库以及需求不同等原因,往往按照自己的方式来实现,这就产生了移植,也是导致众多webkit版本行为不一致的重要原因。

    • webkit嵌入式接口和webkit绑定:在WebCore和webkit Ports之上的层主要是提供嵌入式编程接口,这些接口主要是提供给浏览器调用。由于接口与具体的移植有关,所以有一个与浏览器相关的绑定层。
    • 测试用例:这部分包含布局测试用例和性能测试用例(在图中没有体现)。虽然不同的移植对应的测试用例不一样,但webkit移植还是共享了大量测试用例。每个浏览器使用的webkit必须保证能编译出一个可执行的程序,叫做dumpRenderTree,被用来运行测试用例,并把渲染结果同期望结果作对比。

webkit源代码结构

webkit项目规模庞大,但目录结构十分清晰,通过目录结构可以更好的了解webkit的功能模块,也有助于理解后面对模块和机制的介绍。

图3-2展示的主要是一级目录和二级目录,略去了三级目录。一些重要的三级目录可以参考下方的图3-3。

在一级目录中,重要的目录有四个:LayoutTests、PerformanceTests、Source、Tools,其他目录可忽略。其中,Source目录最重要,是之后主要讲解的部分。Source下重要的子目录包括:JavaScriptCore、Platform、WebCore、WebKit、WebKit2、WTF。详细解释见图3-2。

接下来要讲解一些三级目录,分别属于WebCore和WebKit2。

可以发现图3-1中WebCore包含的模块都在其中,如图3-3。

WebKit2主要包含两种类型的目录,一类是各个进程的目录,例如Web进程、UI进程、网络进程、插件进程以及他们共享的代码;一类是各个移植的主函数入口,可以构建出一个基于WebKit2的最简单的可执行程序,如图3-3。

同在WebKit/Source下的WebKit目录,结构与WebKit2相似,且更简单,此处不做介绍。

基于Blink的Chromium浏览器架构

Chromium浏览器的架构和模块

Chromium也是基于webkit(Blink)的。

Chromium的代码复杂,模块多,结构不是特别清晰,非常让人迷惑。为了方便理解,接下来,将从架构和模块、多进程模型和多线程模型等角度一一剖析。

架构和模块

图3-4展示了Chromium的架构和模块。从图中可以看出,Blink只是其中一部分,和它并列的还有很多其他模块,包括GPU/Command Buffer(硬件加速架构)、V8引擎、沙箱模型、CC(Chromium合成器)、IPC、UI以及未列出的模块等。

在这些模块之上是content模块和content接口,他们是渲染网页功能的抽象。读到这里可能会有疑问,webkit不是渲染网页内容的吗?

的确,浏览器的开发者也可以在webkit的Chromium移植上实现渲染网页内容,但是,没有content模块,就无法获得沙箱模型、跨进程的硬件加速机制、HTML5功能等,因为这些功能都是在content层实现的。

content模块和content接口将下面的渲染机制、安全机制、插件机制等隐藏起来,提供一个接口层,供上层模块或其他项目使用(内部使用如Chromium浏览器、content shell等,外部使用如CEF、Opera浏览器等)。

Chromium浏览器和content shell是构建在content接口上的两个浏览器。

Chromium浏览器是完整的浏览器,也就是我们看到的编译出来的浏览器样式。

content shell是content接口包了一层壳,是一个简单的浏览器,用户可以用来渲染网页内容。

content shell有两个用处:一是用来验证content模块的正确性;二是给外部项目参考来开发基于content接口的浏览器或其他项目。因为Chromium浏览器部分代码未开源,开发者只能依赖content shell来开发。

Android WebView是为了满足Android系统上的WebView而设计的,这部分会在后面详细介绍。

多进程模型

多进程模型的优势:

    • 避免因单个页面的崩溃或不响应而影响浏览器的稳定性。
    • 当第三方插件崩溃时不影响页面和浏览器的稳定性。
    • 方便安全机制的实施,即沙箱模型是基于多进程架构的。

图3-5展示了最常用的Chromium多进程模型(Chromium架构设计灵活,可以通过设置改变进程模型方式)。图中的方框表示进程,连接线表示IPC(进程间通信)。

通过上图,可以看出Chromium浏览器主要包括以下类型:

    • Browser进程:浏览器的主进程,负责浏览器界面的显示、各个页面的管理,是所有其他类型的进程的祖先,负责他们的创建和销毁等工作,有且仅有一个
    • Renderer进程:网页的渲染进程,负责网页的渲染工作。
    • NPAPI插件进程:该进程是为NPAIP类型插件而创建的。创建的基本原则是,每种类型的插件只会被创建一次,而且仅当使用时才被创建。
    • GPU进程最多只有一个,当且仅当GPU硬件加速打开时才会被创建。
    • Pepper 插件进程:同NPAPI插件进程。
    • 其他类型的进程:例如linux下的“Zygote”进程(Renderer进程由它创建),“Sandbox”的准备进程。

桌面系统(Windows、Linux、Mac OS)的Chromium浏览器有以下特征:

    1. Browser进程和页面渲染的进程是分开的,保证了页面渲染导致的崩溃不会影响浏览器主页面的崩溃。
    2. 每个网页是独立的进程,保证了网页之间互不影响。
    3. 插件进程是独立的,插件本身的问题不会影响浏览器的主页面和网页。
    4. GPU硬件加速进程也是独立的。

上面的模型是针对桌面版的Chromium,Android版的稍有不同

    1. GPU进程变成Browser进程的一个线程,也就是GPU线程。
    2. Renderer还是独立的进程,只是会变成了Android的service进程。而且由于Android系统的限制,Renderer进程的数目也有所限制。

Chromium浏览器允许用户配置Renderer进程被创建的方式,简单介绍一下几种模型:

    1. process-per-site-instance:为每个页面都创建一个Renderer进程,不管这些页面是不是来自同一个域。
    2. process-per-site:属于同一个域的共享同一个进程,不属于一个域的创建不同的进程。
    3. process-per-tab:为每个标签页创建一个进程。
    4. single-process:不为任何页面创建进程,所有渲染工作都在Browser进程中进行,他们是Browser进程中的多个线程。
Browser进程和Renderer进程

Browser进程和Renderer进程都是在webkit接口之外由Chromium引入的,这里介绍一下他们是如何利用webkit接口工作的,代码层次见3-6。

最底层的是webkit接口层。一般基于webkit接口层的浏览器直接在上面构建,没有引入复杂的多进程架构。

在webkit接口上的是webkit粘附层。由于Chromium的内部类型与webkit的不一致,所以需要引入一个桥接层。

Renderer进程:位于webkit接口层和Browser进程之间,主要处理进程间通信,接收来自Browser进程的请求,调用webkit接口层,并把webkit的处理结果返回给Browser进程。

Browser进程:负责与Renderer进程间通信。给Renderer进程发送请求,接收Renderer进程返回的处理结果。

web contents:表示网页内容。需要绘制的网页内容可能有多个,所以这里是contents。它同时包括,显示网页内容的一个子窗口(在桌面系统上),这个子窗口被嵌入到浏览器的用户页面,作为一个子标签。

多线程模型

每个进程内部,都有很多线程。

对于Browser进程,多线程的目的是保证用户界面的高响应度,保证UI线程不会被其他费时操作阻碍从而影响用户页面的响应。

在Renderer进程中,Chromium不让其他操作阻止渲染进程的执行,甚至,利用多核优势,将渲染过程管线化,让不同的渲染阶段在不同的线程中进行。

图3-7展示了主线程中的重要线程信息以及如何工作的。(实际上远不止这些线程)

网页的加载和渲染过程,基本工作方式如下:

    1. Browser进程接收到用户请求,首先由UI线程处理,并将相应的任务转给IO线程,IO线程把任务传递给Renderer进程。
    2. Renderer进程的IO线程经过简单解释后交给渲染线程,渲染接受请求,加载和渲染网页(可能需要Browser进程获取资源和GPU进程帮助渲染)。最后把处理结果通过IO线程返回给Browser进程。
    3. Browser进程收到处理结果并把结果绘制出来。

content接口

content接口定义在"content/public"目录下。按功能分为六个部分(每个部分的接口可以分为两类:一是嵌入者调用的接口,二是嵌入者要实现的回调函数):

    1. App:主要与应用程序或线程的创建和初始化有关。
    2. Browser:描述过长。。。此处省略。。。详情参考书
    3. Common:主要定义一些公共的接口,被Browser和Renderer共享。
    4. Plugin:仅有一个接口类,通知嵌入者plugin进程何时创建。
    5. Renderer:描述过长。。。此处省略。。。详情参考书
    6. Utility:工具类接口,主要是让嵌入者参与content接口中的线程创建和消息的过滤。

实践理解现代浏览器

Chromium代码结构

图3-8描述了Chromium的一级目录。

从项目目录和描述来看,Chromium引入了很多新的功能和特性。Chromium除了浏览器,还有ChromiumOS和Chromium Frame。

图中缺少了一个重要的目录,"third_party",该目录保存了Chromium依赖的所有第三方开源项目(超过150个)。Blink的代码也包含在其中。

可以把代码目录结构同图3-4的模块对应来看。

下面重点描述content目录,如图3-9。结构比较容易理解,基本对应了多进程模型中的各种进程类型。

Chromium多进程
Chromium多线程

webkit2

webkit2的架构和模块

相比狭义的webkit,webkit2是一套全新的接口和结构,它的主要目的和思想和Chromium类似,就是,把渲染过程放在单独的进程中,独立于用户界面。

如图3-13,是webkit2 接口和进程模型。自下而上介绍。

    1. 引入了插件进程
    2. 引入网络进程
    3. web进程相当于Chromium的Renderer进程,主要是渲染网页。
    4. UI进程相当于Chromium的Browser进程。接口就暴露在这个进程中,应用程序只需调用接口即可。(应用程序可能是浏览器或者其他使用接口的程序)

webkit和webkit2的嵌入式接口

webkit提供嵌入式接口,该接口表示其他程序可以把渲染网页嵌入在程序中作为其中的一部分,或者用户界面的一部分(一般情况下)。

这些接口按功能可分为六种:

    1. 设置加载网页、获取加载进度、停止加载、重新加载等
    2. 遍历前后浏览器类,可以前进、后退等
    3. 网页的很多设置,如缩放、主题、背景、模式、编码等
    4. 查找网页的内容、高亮等
    5. 触控事件、鼠标事件的处理
    6. 查看网页源代码、显示调试窗口等与开发者有关的接口

webkit2接口不同于webkit接口,他们是不兼容的,但目的差不多,都是提供嵌入式的应用接口。

webkit2 接口大致可以分为两个部分,这里以EFL的移植部分为例介绍

    1. webview相关的接口,表示渲染的设置、渲染过程、界面等
      1. WKView[Ref]:表示的是一个与平台相关的视图
      2. WKContentRef:所有页面的上下文,这些被共享的信息包括localstorage等
      3. WKPageRef:表示网页,也就是浏览的基本单位。
    1. 上面接口所依赖的基础类,被各个移植所共享,既包括容器、字符串等,也包括网页相关的基础类,如URL、请求、网页的设置等。

比较wk2和Chromium的多进程模型

图3-14描述了webkit接口和Chromium多进程的关系,以及和content接口的关系。

webkit2和Chromium的多线程的区别

    1. Chromium使用的仍是webkit接口,而不是webkit2接口,即,Chromium是在webkit接口之上构建的多进程架构。
    2. webkit2希望尽量将多线程架构隐藏起来,而Chromium主要目的是给Chromium提供content接口以便构建浏览器,而不是提供嵌入式接口。
    3. Chromium中每个进程都是从相同的二进制可执行文件启动,而基于webkit2的进程未必。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘大本尊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值