Paul Irish是著名的前端开发工程师,同时他也是 Chrome 开发者关系团队成员,jQuery 团队成员,Modernizr、 Yeoman、CSS3 Please 和 HTML5 Boilerplate 的 lead developer。针对你们对 WebKit 的种种误解,他在本身的博客发表了《WebKit for Developers》一文,试图为你们解惑:ios
对许多开发者来讲,WebKit 就像一个黑盒。咱们把 HTML、CSS、JS 和其余一大堆东西丢进去,而后 WebKit 魔法般的以某种方式把一个看起来不错的网页展示给咱们。但事实上,Paul 的同事 Ilya Grigorik 说:css3
WebKit 才不是个黑盒。它是个白盒。而且,它是个打开的白盒。web
因此让咱们来花些时间了解这些事儿:算法
- 什么是 WebKit?
- 什么不是 WebKit?
- 基于 WebKit 的浏览器是如何使用 WebKit 的?
- 为何又有不一样的 WebKit?
如今,特别是 Opera 宣布将浏览器引擎转换为 WebKit 以后,咱们有不少使用 WebKit 的浏览器,可是咱们很难去界定它们有哪些相同与不一样。下面我争取为这个谜团作些解读。而你也将会更懂得判断浏览器的不一样,了解如何在正确的地方报告 bug,还会了解如何在特定浏览器下高效开发。chrome
标准 Web 浏览器组件windows
让咱们列举一些现代浏览器的组件:后端
- HTML、XML、CSS、JavsScript 解析器
- Layout
- 文字和图形渲染
- 图像解码
- GPU 交互
- 网络访问
- 硬件加速
这里面哪些是 WebKit 浏览器共享的?差很少只有前两个。其余部分每一个 WebKit 都有各自的实现,所谓的“port”。如今让咱们了解一下这是什么意思……
WebKit Ports 是什么?
在 WebKit 中有不一样的“port”,可是这里容许我来让 WebKit hacker,Sencha 的工程主管 Ariya Hidayat 来解释:
WebKit 最多见的参考实现是 Apple 在 Mac OS X 上的实现(这也是最先和最原始的 WebKit 库)。可是你也能猜到,在 Mac OS X 下,许多不一样的接口在不少不一样的原生库下被实现,大部分集中在CoreFoundation。举例来讲,若是你定义了一个纯色圆角的按钮,WebKit 知道要去哪里,也知道要如何去绘制这个按钮。可是,绘制按钮的工做最终仍是会落到CoreGraphics去。
上面已经提到,CoreGraphics 只是 Mac port 的实现。不过 Mac Chrome 用的是Skia。
随时间推移,WebKit 被“port”(移植)到了各个不一样的平台,包括桌面端和移动端。这种作法被称做“WebKit port”。对 Windows 版 Safari 来讲,Apple 经过(有限实现的)Windows 版本 CoreFoundation 来 port WebKit。
……不过 Windows 版本的 Safari如今已经死掉了。
除此以外,还有不少不少其它的“port”(参见列表)。Google 建立并维护着它的 Chromium port。这其实也是一个基于 Gtk+ 的 WebKitGtk。诺基亚经过收购 Trolltech,维护着以QtWebKit module而闻名的 WebKit Qt port。
让咱们看看其中一些 WebKit ports:
- Safari
- OS X Safari 和 Windows Safari 使用的是不一样的 port
- 用于 OS X Safari 的 WebKit Nightly 之后会渐渐成为一个边缘版本
- Mobile Safari
- 在一个私有代码分支上维护,不过代码如今正在合并到主干
- iOS Chrome(使用了 Apple 的 WebView,不事后面的部分有不少不一样)
- Chrome(Chromium)
- 安卓 Chrome(直接使用 Chromium port)
- Chromium 也驱动了Yandex Browser、 360 Browser、Sogou Browser,很快,还会有 Opera。
- 还有不少: Amazon Silk、Dolphin、Blackberry、QtWebKit、WebKitGTK+、The EFL port (Tizen)、wxWebKit、WebKitWinCE……
不一样的 port 专一于不一样的领域。Mac 的 port 注意力集中在浏览器和操做系统的分割上,容许把 ObjectC 和 C++ 绑定并嵌入原生应用的渲染。Chromium 专一在浏览器上。QtWebKit 的 port 在他的跨平台 GUI 应用架构上给 apps 提供运行时环境或者渲染引擎。
WebKit 浏览器共享了那些东西?
首先,让咱们来看看这些 WebKit ports 的共同之处:
(做者注:颇有意思,这些内容我写了不少次,每次 Chrome 团队成员都给我纠正错误,正如你看到的……)
- “WebKit 在使用相同的方式解析 WebKit。”——实际上,Chrome 是惟一支持多线程 HTML 解析的 port。
- “一旦解析完成,DOM 树也会构建成相同的样子。”——实际上 Shadow DOM 只有在 Chromium 才被开启。因此 DOM 的构造也是不一样的。自定义元素也是如此。
- “WebKit 为每一个人建立了‘window’对象和‘document’对象。”——是的,尽管它暴露出的属性和构造函数能够经过feature flags来控制。
- “CSS 解析都是相同的。将 CSS 解析为对象模型是个至关标准的过程。”——不过,Chrome 只支持 -webkit- 前缀,而 Apple 和其余的 ports 支持遗留的 -khtml- 和 -apple- 前缀。
- “布局定位?这些是基本生计问题啊”—— 尽管 Sub-pixel layout 和 saturated layout 算法是 WebKit 的一部分,不过各个 port 的实现效果仍是有不少不一样。
因此,状况很复杂。
就像 Flickr 和 GitHub 经过 flag 标识来实现本身的功能同样,WebKit 也有相同处理。这容许各个 port 自行决定是否启用WebKit 编译特性标签的各类功能。经过命令行开关,或者经过about:flags还能够控制是否经过运行时标识来展现功能特性。
好,如今让咱们再尝试一次搞清楚 WebKit 究竟有哪些相同…
每一个 WebKit port 有哪些共同之处
- DOM、winow、document
- CSS 对象模型
- CSS 解析,键盘事件处理
- HTML 解析和 DOM 构建
- 全部的布局和定位
- Chrome 开发工具和 WebKit 检查器的 UI 与检查器
- contenteditable、pushState、文件 API、大多数 SVG、CSS Transform math、Web Audio API、localStorage 等功能
- 不少其余功能与特性
这些领域如今有点儿模糊,让咱们尝试把事情弄得更清楚一点。
什么是 WebKit port 们并无共享的:
- GPU 相关技术
- 3D 转换
- WebGL
- 视频解码
- 将 2D 图像绘制到屏幕
- 解析方式
- SVG 和 CSS 渐变绘制
- 文字绘制和断字
- 网络层(SPDY、预渲染、WebSocket 传输)
- JavaScript 引擎
- JavaScriptCore 在 WebKit repo 中。V8 和 JavaScriptCore 被绑定在 WebKit 中。
- 表单控制器的渲染
- <video> 和 <audio> 的元素表现和解码实现
- 图像解码
- 页面导航 前进 / 后退
- pushState() 的导航部分
- SSL 功能,好比 Strict Transport Security 和 Public Key Pins
让咱们谈谈其中的 2D 图像部分: 根据 port 的不一样,咱们使用彻底不一样的库来处理图像到屏幕的绘制过程:
更宏观一点来看,一个最近刚添加的功能:CSS.supports() 在除了没有 css3 特性检测功能的 win 和 wincairo 这两个 port 以外,在其它全部 port 中都可用。
如今到了卖弄学问的技术时间。上面讲的内容其实并不正确。事实上那是 WebCore 被共享的东西。而 WebCore 实际上是当你们讨论 HTML 和 SVG 的布局、渲染和 DOM 处理时提到的 WebKit。技术上讲,WebKit 是 WebCore 和各类 ports 之间的绑定层,尽管一般来讲这个差异并不那么重要。
一个图表应该能够帮助你们理解:
WebKit 中的许多组件都是能够更换的(图中标灰色的部分)。
举个例子来讲,Webkit 的 JavaScript 引擎,JavaScriptCore,是 WebKit 的默认组件。(它最初是当 WebKit 从 KHTML 分支时从 KJS 演变来的)。同时,Chromium port 用 V8 引擎作了替换,还使用了独特的 DOM 绑定来映射上面的组件。
字体和文字渲染是平台上的重要部分。在 WebKit 中有两个独立的文字路径:Fast 和 Complex。这二者都须要平台特性的支持,可是 Fast 只须要知道如何传输字型,而 Complex 实际上须要掌握平台上全部的字符串,并说“请绘制这个吧”。
"WebKit 就像一个三明治。尽管 Chromium 的包装更像是一个墨西哥卷。一个美味的 Web 平台墨西哥卷。"
—— Dimitri Glazkov, Chrome WebKit hacker,Web Components 和 Shadow DOM 拥护者。
如今,让咱们放宽镜头看看一些 port 和一些子系统。下面是 WebKit 的 5 个 port;尽管它们共享了 WebCore 的大部分,但考虑一下它们的 stack 有哪些不一样。
Chrome (OS X) | Safari (OS X) | QtWebKit | Android Browser | Chrome for iOS | |
---|---|---|---|---|---|
Rendering | Skia | CoreGraphics | QtGui | Android stack/Skia | CoreGraphics |
Networking | Chromium network stack | CFNetwork | QtNetwork | Fork of Chromium’s network stack | Chromium stack |
Fonts | CoreText via Skia | CoreText | Qt internals | Android stack | CoreText |
JavaScript | V8 | JavaScriptCore | JSC (V8 is used elsewhere in Qt) | V8 | JavaScriptCore (without JITting) * |
*iOS Chrome 注:你可能知道它使用 UIWebView。因为 UIWebView 的能力限制。它只能使用移动版 Safari 的渲染层,JavaScriptCore(而不是 V8)和单进程模式。然而,大量的 Chromium 代码仍是起到了调节做用 ,好比网络层、同步、书签架构、地址栏、度量工具和崩溃报告。(同时,因为 JavaScript 不多成为移动端的瓶颈,缺乏 JIT 编译器只有很小的影响。)
好吧,那么咱们该怎么办?
如今全部 WebKit 彻底不一样了,我好怕。
别这样!WebKit 的 layoutTests 覆盖面很是广(据最新统计,有 28,000 个 layoutTests),这些 test 不只针对已存在的特性,并且针对任何发现的回归。实际上,每当你探索一些新的或难懂的 DOM/CSS/HTML5 特性时,在整个 web 平台上,layoutTests 常常已经有了一些奇妙的小 demo。
另外,W3C 正在努力研究一致性测试套件。这意味着咱们能够期待使用同一个测试套件来测试不一样的 WebKit port 和浏览器,以此来得到更少的怪异模式,和一个带来更少的怪癖模式和更具互操做性的 web。对全部参加过Test The Web Forward活动的人们……致谢!
Opera 刚刚迁移到了 WebKit 了。会怎样?
Robert Nyman 和 Rob Hawkes 也谈到了这个 ,可是我会再补充一些:Opera 在公告中明显指出Opera 将采用 Chromium。这意味着 WebGL,Canvas,HTML5 表单,2D 图像实现——Chrome 和 Opera 将在全部这些功能上保持一致。API 和后端实现也会彻底相同。因为 Opera 是基于 Chromium,你能够有足够的信心去相信你的尖端工做将会在 Chrome 和 Opera 上得到兼容。
我还应该指出,全部的 Opera 浏览器都将采用 Chromium:包括他的 Windows,Mac、Linux 版本,和 Opera Mobile(彻底成熟的移动浏览器)。甚至 Opera Mini 都将使用基于 Chromium 的服务器渲染集群来替换当前的基于 Presto 的服务器端渲染。
……那 WebKit Nightly 是什么?
它是 WebKit 的mac port ,和 Safari 运行的二进制文件同样(尽管会替换一些底层库)。由于苹果在项目中起主导地位,因此它的表现和功能与 Safari 的老是那么一致。在不少状况下,当其它 port 可能会试验新功能的时候,Apple 却显得相对保守。无论怎样,若是你想我用中学同样的类比,想一想这个好了:WebKit Nightly 对于 Safari 就像 Chromium 对于 Chrome。
一样的,Chrome Canary 有着最新的 WebKit 资源。
告诉我更多的 WebKit 内幕吧。
就在这儿了,小伙子:
扩展阅读:
- WebKit internals technical articles | webkit.org
- WebKit: An Objective View | Robert Nyman & Rob Hawkes (译者注:本文在 InfoQ 有受权发布的中文译文)
- your webkit port is special (just like every other port) | Ariya Hidayat
- Getting Started With the WebKit Layout Code | Adobe Web Platform Blog
- WebKit Documentation Overview | Arun Patole
- Rendering in WebKit, by Eric Seidel | YouTube
- web performance for the curious | Ilya Grigorik