《WebKit技术内幕》阅读摘要 —— WebKit 架构和模块

2,823 阅读5分钟

image

WebKit 架构及模块

特征:支持不同浏览器,一部分代码共享,另外一部分不同,不同部分称为 WebKit 的移植(Ports),如下图中虚线框表示不同浏览器中实现普遍不同。

image

  • 最底层是操作系统,WebKit 可以在不同的操作系统上工作
  • 操作系统之上的就是 WebKit 依赖的第三方库,这些库是 WebKit 运行的基础
  • 再往上一层就是 WebKit 项目了,图中又将其分为两层
    • WebCore 部分包含了目前被各个浏览器所使用的共享部分,是加工渲染网页的基础。包括 HTML(解释器)、CSS(解释器)、SVG、DOM、渲染树(ReaderObject 树、ReaderLayer 树等)、 Inspector(Web Inspector 开发者工具、调试网页)
    • JavaScriptCore 引擎是 WebKit 中的默认 JavaScript 引擎,WebKit 中对 JavaScript 引擎的调用是独立引擎的。例如 Chromium 中替换为 V8 引擎
    • WebKit Ports 指的是 WebKit 中的非共享部分,包括硬件加速架构、网络栈、视频解码、图片解码等
  • WebCoreWebKit Ports 之上的层主要提供嵌入式编程接口,提供给浏览器调用。接口层的定义也与移植密切相关,而不是 WebKit 有一个统一接口。

WebKit2 嵌入式接口不是 WebKit 嵌入式接口的简单修改,而是为了浏览环境的安全性和稳定性原因考虑而引入了跨进程的架构。由苹果于 2010 年 4 月发布,WebKet2 的进程结构模型中至少有两个进程,其一是 WebKit2 所在的浏览器或者 Web 平台的 UI 进程,其二是 Web 进程,也就是网页渲染所在的进程

基于 Blink 的 Chromium 浏览器结构

Chromium 浏览器的架构及模块

Chromium 也是基于 WebKit(Blink)的,并且将很多先进的理念引入到浏览器中领域,可以了解如何基于 WebKit 构建浏览器。

架构及模块

Chromium 的架构和主要模块如下:

image

从图中可以看到,Blink 只是其中的一块,还有众多的 Chromium 模块,包括 GPU/CommandBuffer (硬件加速架构)、V8 JavaScript 引擎、沙箱模型、CC(Chromium Compositor | Chromium 合成器)、IPC(进程间通信)、NPAPI(Netscape Plugin API)、UI 等

再向上就是 “Content 模块” 和 “Content API(接口)”,他们是 Chromium 对渲染网页功能的抽象。沙箱模型、跨进程的 GPU 硬件加速机制、众多的 HTML5 功能都是在 Content 层里实现,将渲染机制、安全机制和插件机制隐藏起来,提供一个接口供上层模块使用。

多进程模型

好处:

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

Chromium 浏览器中主要包含的进程类型

  • Browser 进程:浏览器主进程,仅有一个
  • Renderer 进程:渲染进程,负责页面渲染,可能有多个,但不一定同打开的网页数量一致
  • NPAPI 插件:为 NPAPI 类型的插件创建,每种类型插件创建一次,仅当使用时才创建,多个网页中共享一个进程但有不同的实例。
  • GPU 进程:仅当 GPU 硬件加速打开时才会被创建
  • PPAPI 进程:Pepper 插件创建的进程
  • 其他类型进程:Linux 下的“Zygote”进程,Renderer 进程由它创建。“Sandbox”准备进程

Android 版不支持插件,GPU 进程变成 Browser 进程的一个线程,Renderer进程会演变为 Android 上的服务(service)进程。并且有“影子”标签,会将后台的网页所使用的渲染设施都清除,当用户切换的时候需要重新加载渲染。

Renderer 进程被创建的方式:

  • Process-per-site-instance:每个页面都有独立的 Render 进程
  • Process-per-site:同一个域的页面共享同一个进程
  • Process-per-tab:(默认)每个标签页
  • Single process:所有渲染工作都在 Browser 进程中进行,Android WebView 中使用
Browser 进程和 Renderer 进程

因为 Chromium 中的一些类型和 WebKit 内部不一致,所以 Chromium 没有直接使用 WebKit 的接口而是用粘附层进行了桥接。并在桥接层之上添加了用于进程间通信的 Renderer,将渲染封装成为单独的服务,屏蔽具体实现。

Browser 进程中也需要 RendererHost 来负责进程通信,再向上就是 Web Contents,也就是一个一个的标签页和上层的浏览器UI

image

多线程模型

每个进程内都有很多线程,保证 Browser 进程中的 UI 线程不会被任何其他费时操作影响。Renderer 进程中,不让其他操作阻止渲染线程的快速执行。并且将渲染过程管线化,让渲染可以在不同的线程执行(渲染过程分为很多独立阶段,每个阶段创建一个线程,利用CPU多核能力加快渲染,像流水线一样提高并发)

网页加载渲染过程

  • Browser 进程收到用户请求,先 UI 线程处理,转发给 IO 线程,然后传递给 Renderer 进程
  • Renderer 进程有自己的 IO 线程,经过简单的解释后交给渲染进程渲染,渲染过程可能需要 Browser 进程获取资源,GPU 进程帮助渲染。渲染结果由 IO 线程传递给 Browser 进程
  • Browser 进程绘制

进程间通信:绝大多数场景使用事件和 Chromium 新创建的任务传递机制,仅在非用不可的情况下使用锁或线程安全对象。

Content 接口

Content 接口不仅对多进程渲染提供一层封装,并且支持所有 HTML5 功能,GPU 硬件加速功能,沙箱机制。

WebKit2

WebKit2 是一套权限的结构和接口,目的同 Chromium 类似,将渲染过程放在单独进程中完成。

比较 WebKit2 和 Chromium

  • Chromium 使用 WebKit 接口,而不是 WebKit2
  • Chromium 是将渲染封装成为服务,在服务的基础上构建多进程。而 WebKit2 希望将多进程结构隐藏起来,直接在渲染中实现多进程模型。

更多

《WebKit技术内幕》知识提炼 —— 资源加载和网络栈