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