原文:http://www.paulirish.com/2013/webkit-for-developers/
Paul Irish 大湿为我们带来了这篇开年大作,文章深入浅出的阐述了各 Webkit port 的迥异。文笔细腻,是一篇不可多得的 Webkit 入门开胃菜。
为了让大家第一时间更好的品尝这道大菜,@一丝yisi 特别邀请了几位 Webkit 专业开发人士作为本文的翻译顾问,在此表示由衷的感谢。
本文涉及到许多的专业术语。我会尽量补充一些相关资料的链接。翻译不当之处。欢迎批评指正。
对于很多开发人员而言,WebKit 是一个黑盒子。我们把 HTML, CSS, JS 和一堆资源放进去,然后 WebKit 以某种方式。奇异地变出一个中看又中用「美观而有用」的网页。其实,如同我同事 Ilya Grigorik 所说 …
WebKit 它不是一个黑盒子。而是一个白盒子,而且是一个开放的白盒子。
那么让我们花一点时间来理清一些东西:
WebKit 是什么?
WebKit 不是什么?
基于 WebKit 的浏览器使怎样运用 WebKit ?
为什么全部的 WebKit 并不一样「呢」?
尽管如今我们已经有了非常多 Webkit 浏览器了,特别是有消息称 Opera 也已经转移到 WebKit 了,可是想要理解他们的同样点和不同点还是挺难的。以下我将側重讲这方面,你将能更好的分辨浏览器的差异。在合适的 bug 跟踪系统提交 bug,并了解怎样更加高效的针对特定的浏览器进行开发。
标准的 Web 浏览器组件 让我们看一下现代 web 浏览器的几个组件:
- 解析(HTML, XML, CSS, JavaScript)
- 排版(Layout)
- 文字和图像渲染
- 图像解码
- GPU 交互
- 网络接入
- 硬件加速
那么哪些是基于 WebKit 的浏览器所共享的呢? 差点儿仅仅有前两项。
其他的由各自的 WebKit port 负责。让我们回想下这意味着什么? WebKit Port 尽管 Webkit 有不同的 ”port”,但请同意我引用来自 Sencha 的 WebKit hacker 兼 eng 主管— Ariya Hidayat 解释一下 :
WebKit 最常见的參考实现是 Apple 自己的执行在 Mac OS X 上的WebKit 实现(这也是最早最原始的 WebKit 库)。正如你所知。在 Mac OS X 上各种接口的实现使用不同的本地库,大多集中在 CoreFoundation 。比方,你定义了一个带有特别的圆角的平面彩色button。那么 WebKit 会知道在哪里以及怎样画绘制这个button。但是。终于实际画绘制button的职责(作为用户显示器上的像素)还是落到了 CoreGraphics 身上。
如上所述。仅仅有 Apple 自己在 Mac 上的实现是使用 CG。Chrome 在 Mac 上的实现使用的是 Skia。
随着时间推移,WebKit 被移植到不同的平台,包含桌面和移动端。这样的做法通常被称作“一个 WebKit port”。对于 Safari 浏览器的 Windows 版本号。Apple 也把自己的 WebKit 移植到 Windows 上。同一时候使用 Windows 版(阉割版)的 CoreFoundation 库。
虽然 Windows 版 Safari 如今挂了 。
此外,还有更多的”port”(查看
所有的列表)。Google 创建了一个持续维护的 Chromium port。
还有。这是基于 GTK + 的 WebKitGtk。Nokia(通过它收购的 Trolltech 公司)维护 Qt 的 WebKit 移植版本号,一般叫做QtWebKit 模块。
(译者注:后来又廉价卖了,如今 Qt 属于 Digia 公司)
一些 WebKit port
- Safari
- OS X 版和 Windows 版的 Safari 是两个不同的 port
- 用于 Safari 的 WebKit nightly 将会慢慢成为一个边缘化的版本号……
- Mobile Safari
- 一開始在内部的私有分支上维护。只是近期代码也合并回主干(being upstreamed)。
(译者注:upstream 是开源项目的术语。指其他人或者公司从主干代码开出来的私有分支的代码又一次提交回主干)
- iOS 版的 Chrome(使用 Apple 的 WebView;后面有很多其他关于它的不同之处)
- 一開始在内部的私有分支上维护。只是近期代码也合并回主干(being upstreamed)。
- Chrome (Chromium)
- 安卓版 Chrome (直接使用 Chromium port)
- Chromium 也驱动 Yandex 浏览器 ,360 浏览器 。搜狗浏览器 (译者注:事实上国内的壳浏览器太多了。你懂的)等,以及将来的 Opera。
- Android 浏览器
- 使用眼下最新的 WebKit 代码
- 还有非常多 port :Amazon Silk(亚马逊 Silk 浏览器)。 Dolphin(海豚浏览器)。Blackberry(黑莓浏览器),QtWebKit。WebKitGTK+,EFL port (Tizen),wxWebKit,WebKitWinCE 等等。
不同的 port 能够有不同的側重点。
Mac port 关注的是浏览器内核和操作系统相关的实现部分的分离,它通过 Obj-C 和 C++ 代码把(WebKit)渲染引擎嵌入到本地应用中。 Chromium 则很多其他关注浏览器本身。而 QtWebKit 则把它的 WebKit 实现作为一个执行时的库或者渲染引擎,同其跨平台 GUI 应用程序框架一起提供给其他应用使用。
哪些是全部 WebKit 浏览器所共享的?
首先,让我们回想一下全部 WebKit port 的共同点。
这非常有趣,我试着写了几次。
每次都会被 Chrome 团队成员斧正,正如你将会看到的……
1. 首先,WebKit 以相同的方式解析 HTML 。
好吧,除了 Chromium。它是迄今为止唯一支持 threaded HTML 解析的 port(译者注:Last week in WebKit: Threaded HTML parser and background blending)。
2.然而一经解析,DOM 树构造依旧相同。所以,实际上仅仅有在 Chromium port 中 Shadow DOM 被打开的情况下, DOM 结构才会改变。当然这相同适用于自己定义元素。
3. WebKit 都会创建了一个 window 对象和 document 对象。
使得通过它暴露出来的属性和构造器(译者注:某种函数)能够在 feature flags 选择打开。
4.CSS解析基本是一样的,把你的 CSS 文件解析成(内部的)CSS 对象模式还是一个比較标准的过程。
是的。虽然 Chrome 仅接受 -webkit- 前缀,然而 Apple 和其他的 port 接受遗留前缀像 -khtml- 和 -apple-。
5.排版。定位?好吧。也来点面包和黄油吧!
Sub-pixel layout 和 saturated layout (译者注:已经加入链接)算法是 WebKit 的一部分,可是各 port 之间存在差异。
6. 好极了。
所以,事情非常复杂。
就像 Flickr 和 Github 通过 flags 标识实现特性,WebKit 也是这么做的。同意 port 通过 WebKit 的编译特性标识 。 启用或禁用各种功能。这些特性能够作为执行时标识被暴露,也能够通过命令行开关(Chromium 是这样) ,或者通过配置 about:flags 。
好吧,让我们又一次归纳下各 WebKit 的共同点……
WebKit port 的共同点
- DOM,window, document
- 大致同样
- CSSOM
- CSS 解析,属性/值处理
- 无供应商前缀处理
- HTML 解析和 DOM 结构
- 假设我们仅仅考虑 Web 组件。它是同样的
- 全部的布局和定位
- Flexbox。浮动,块级格式化上下文… 全部这些是共享的
- Chrome DevTools ( WebKit Inspector) 的 UI 和各种工具
- 虽然去年4月以来,Safari 为 Safari Inspector 放弃了自有的非 Webkit 的闭源 UI
- contenteditable, pushState,File API。大部分的 SVG。CSS Transform 公式。 Web Audio API,localStorage
- 特性虽然后端不同。每个 port 的 localStorage 可能使用不同的存储层。Web Audio API 可能使用不同的 audio API
- 大量其他的特性和功能
哪些是 WebKit port 不共享的
- 执行在 GPU 上的
- 3D变换
- WebGL
- 视频解码
- 屏幕上的 2D 画图
- 抗锯齿方法
- SVG & CSS 渐变渲染
- 文字渲染&断字
- 网络堆栈(SPDY。预渲染。WebSocket 传输)
- JavaScript 引擎
- JavaScriptCore 在 WebKit repo. 它和 V8 绑定在 WebKit 里
- 表单控件渲染
- <video> & <audio> 元素行为(以及编解码器支持)
- 图像解码
- 导航 前进/后退
- pushState() 的导航部分
- SSL 特性像严格传输安全性(Strict Transport Security)和公钥
看以下这些: 2D 图形方面依赖于不同的 port 。我们用全然不同的库把它绘制到屏幕上:
或者更微观一点,近期的新特性:CSS.supports() 除了 win 和 wincairo, 全部的 port 都可用 ,同一时候它们没有启用 css3 conditional (css3 特性检測)特性。
既然我们了解了这些,是时候更加深入一些了。
其实以上的叙述是不对的。 WebCore 是共享的。WebCore 是一个针对 HTML 和 SVG 的排版、渲染和文档对象模型(DOM)的库,它就是人们通常所说的 WebKit 。实际上“WebKit ”是 WebCore 和 port 的绑定层。虽然在扯淡时这样的差别是不重要的。
下图应该有所帮助:
WebKit 里面很多的组件是可交换的(上图灰色区域)。
举个样例。起初,WebKit 的默认 JavaScript 引擎是 JavaScriptCore 。
(它基于最初的 KJS (源于 KDE)。WebKit 開始仅仅是 KHTML 的一个 fork 分支)。
后来,Chromium port 替换为 V8,然后使用独立的 DOM 绑定机制映射上去就完事了。
字体和文本渲染占一个平台的非常大一部分。WebKit 有2个单独的文本路径:高速(Fast)和复杂(Complex)。
两者都须要平台特定(port-side)的支持,但高速仅须要知道怎样 blit glyphs (传输符号)(WebKit 为平台做了缓存)。复杂确实须要转换整个字符串到平台层然后说“请绘制这个”。
WebKit 像一个三明治。虽然在 Chromium 中更像墨西哥玉米卷。一个美味的 web 平台玉米卷。
”——Dimitri Glazkov。Chrome WebKit hacker。Web 组件和 Shadow DOM 的拥护者。
如今。让我们放大镜头看看一些 port 和一些子系统。以下是 WebKit 的5个 port。虽然它们共享WebCore 的大部分,但它们的 stacks 是不同的。
* iOS 版 Chrome 注解:你可能知道它使用 UIWebView,因为 UIWebView 的能力意味着它仅仅能使用像移动版 Safari 那样的渲染层。JavaScriptCore (替代 V8)。单进程模式。
虽然如此,大量的 Chromium 代码起衔接作用 ,比如网络层,同步和书签基础设施,地址栏,度量和崩溃报告。(同一时候,更重要的是,JavaScript 非常少成为移动端的瓶颈,缺乏 JIT 编译器(译者注:具体资料)仅仅有非常小的影响。)
好吧。那么我们该怎么办? 如今全部 WebKit 全然不同了,我弱弱的表示害怕。
不是必需!
WebKit 的 layoutTests 覆盖面很广(最新统计是28,000 个 layoutTests),不仅针对已存在的特性。并且针对不论什么发现的回归。实际上,每当你探索一些新的或难懂的 DOM/CSS/HTML5 特性时。layoutTests 经常已经有了奇异的最小化的演示样例。
此外,W3C 正在努力研究一致性測试套件 。
这意味着我们能够期待不同的 WebKit port 和全部浏览器使用相同的測试套件測试,带来更少的怪癖模式和更彼此协作的网络。全部參加过 Test The Web Forward 大会(译者注:比方去年在北京的分会场) 为此做出努力的人们,谢谢你们。
Opera 刚刚转移到 WebKit了。有何影响呢?
Robert Nyman 和 Rob Hawkes 也谈到了这个 ,可是我将补充一些:Opera 公告的一个明显的部分是 Opera 将採用 Chromium。这意味着 WebGL。Canvas。HTML5 表单,2D 图像实现——全部这些 Chrome 和 Opera 将保持一致。
相同的 APIs。相同的后端实现。因为 Opera 是基于 Chromium,你能够深感自信。你未来的工作能够同一时候兼容 Chrome 和 Opera 。
我也应该指出全部的 Opera 浏览器 将採用 Chromium。因此 Windows。Mac 和 Linux 版 Opera,以及 Opera Mobile(全然成熟的移动浏览器)。甚至 Opera Mini 轻client。将使用基于 Chromium 的渲染替换当前的基于 Presto 的server端渲染。
WebKit Nightly。是什么?
它是 WebKit 的一个 mac port ,内部执行跟 Safari 一样的二进制文件(虽然会替换一些底层库)。因此它的行为和特性跟 Safari 全一样。假设你想回到从前,能够考虑它……总之。WebKit Nightly 面向 Safari 。 Chromium 面向 Chrome 。 Chrome Canary 包括最进一两天之内的 WebKit 资源。