一、WebKit 前世今生:浏览器内核发展史

大家好,我是老张。今天咱们聊聊 WebKit 的来龙去脉。

做 Android 开发的,尤其是做 WebView 相关工作的,绕不开 WebKit。你想想看,每天上亿台 Android 手机都在跑 WebView,底层就是它。但很多人用了好几年,都不知道这玩意儿到底怎么来的。

今天我就把这段历史掰开揉碎,讲给你听。

1.1 浏览器内核的早期格局

90年代末,浏览器市场还是 IE 的天下。那时候 Netscape 还没死透,但已经奄奄一息了。真正有点技术追求的,都在关注 KDE 社区。

KDE 是 Linux 上的桌面环境,他们需要一个浏览器。于是 1998 年,KHTML 诞生了。

同期还有几个重要的内核:

  • Trident —— IE 的内核,闭源,Windows 独占
  • Gecko —— Netscape 后来演变成 Firefox,开源
  • Presto —— Opera 自研内核,小而快
  • KHTML —— KDE 项目,开源,轻量

说实话,KHTML 当时并不起眼。我早年做 Linux 桌面开发时,用过 Konqueror 浏览器,就是基于 KHTML 的。那时候感觉还行,但跟 IE 比差远了。

1.2 WebKit 的起源:从 KHTML 到 WebKit

2001 年,苹果开始做 Safari 浏览器。他们需要一个内核,但不想从头造轮子。考察了一圈,最后选了 KHTML。

为什么选 KHTML?我个人分析有三个原因:

  1. 代码质量好 —— KHTML 虽然小,但架构清晰,扩展性强
  2. LGPL 协议 —— 苹果可以闭源使用,只要开源修改部分
  3. 跨平台 —— 本来就是为 Linux 写的,移植到 macOS 不难

2003 年,苹果 fork 了 KHTML,改名叫 WebKit。嗯,这里要注意:苹果不是直接拿来用,而是做了大量改造。他们重写了渲染引擎,加上了自己的 JavaScript 引擎(最初是 KJS,后来自己写了 JavaScriptCore)。

关键节点:2005 年,WebKit 正式开源。苹果把代码放到了 Apache 协议下,从此 WebKit 成了真正的开源项目。

我在项目中遇到过一件事:有同事问,为什么 WebKit 的代码里还有 KHTML 的注释?其实很正常,底层的排版引擎核心还是 KHTML 那套,只是上层全换了。

1.3 WebKit 与 Blink 的分家

2013 年,Google 做了一个让整个行业震动的决定:从 WebKit fork 出来,自己做 Blink。

为什么会这样?说白了,就是利益冲突。

当时的情况是这样的:

  • Google 是 WebKit 最大的贡献者,但苹果是项目的主导者
  • Google 想推的多进程架构,苹果不感冒
  • Google 想加速开发节奏,苹果觉得太激进
  • 两个公司的产品方向完全不同:Google 要服务 Chrome,苹果要服务 Safari

我曾经参与过一个跨平台浏览器项目,深刻体会到这种痛苦。你想想看,你提交的代码,要等另一个公司的审核,人家还跟你有竞争关系。这谁受得了?

避坑指南:如果你在项目中需要同时支持 WebKit 和 Blink,一定要注意 CSS 前缀的差异。WebKit 用 -webkit-,Blink 也兼容,但有些新特性只有 Blink 支持。我曾经因为没注意这个,导致某个动画在 Safari 上直接崩了。

分家之后,Blink 发展极快。Chromium 项目成了浏览器界的 Linux,几乎所有主流浏览器(Chrome、Edge、Opera、Brave、Vivaldi)都基于它。而 WebKit 则成了苹果的专属内核。

1.4 Android 为何选择 WebKit

2007 年,Google 发布 Android 1.0。当时他们面临一个选择:用什么浏览器内核?

选项其实不多:

内核 优势 劣势
WebKit 开源、轻量、跨平台、性能好 苹果主导,但协议友好
Gecko 功能强大 太重,不适合移动设备
Trident 兼容性好 闭源,Windows 独占
Presto 速度快 闭源,Opera 独占

答案很明显了。WebKit 是唯一一个既开源又轻量、还能跨平台的选择。而且 Google 当时已经在用 WebKit 做 Chrome 了(2008 年发布),技术积累很足。

我个人的看法是:Android 选 WebKit,其实是选了一条最稳妥的路。你想想看,2007 年的移动设备,内存才 128MB,CPU 才 400MHz。Gecko 那种庞然大物根本跑不动。WebKit 的架构设计非常精简,渲染引擎和 JavaScript 引擎可以独立升级,这对移动设备来说太重要了。

小技巧:Android 4.4 之前用的是 WebKit,之后换成了 Chromium 内核(Blink)。如果你在做老设备兼容,要注意这个分水岭。我建议用 Build.VERSION.SDK_INT 判断版本,19 以下用 WebKit 特性,19 以上用 Chromium 特性。

1.5 知识体系总览

下面这张图,把 WebKit 的发展脉络和核心组件串起来了。我建议你多看几遍,对后续学习很有帮助。

WebKit 发展历程与核心架构 1998 KHTML 诞生 2003 苹果 fork 出 WebKit 2007 Android 选用 WebKit 2013 Google fork 出 Blink WebKit 核心架构 WebCore HTML 解析 / CSS 渲染 / 布局 JavaScriptCore JS 解析 / JIT 编译 / GC WebKit Ports 平台适配层 / 网络 / 字体 平台层(macOS / iOS / Android / Linux) WebKit 分支 Safari / 旧版 Android 浏览器 Blink 分支 Chrome / Edge / Opera / Android WebView

这张图里,我特意把 WebCore、JavaScriptCore、Ports 三层画出来了。这是 WebKit 最核心的设计:跨平台的核心引擎 + 平台相关的适配层。Android 当年选它,就是看中了这个架构的灵活性。

1.6 小结

好了,这一章的内容就这些。总结几个关键点:

  • WebKit 源自 KHTML,苹果在 2003 年 fork 并重写
  • 2013 年 Google fork 出 Blink,从此分道扬镳
  • Android 选 WebKit 是因为它轻量、开源、跨平台
  • WebKit 的三层架构(WebCore + JavaScriptCore + Ports)是它的核心优势

下一章,我们会深入 WebKit 的架构设计,看看它到底是怎么工作的。到时候我会拿一个真实的渲染流程来拆解,保证让你看明白。


公众号:蓝海资料掘金营,微信deep3321