開發者須要瞭解的 WebKit

 
  • 彭超

2013 年 3 月 18 日html

話題:JavaScriptHTML5語言 & 開發前端

 

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)
  • 還有不少: 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 團隊成員都給我糾正錯誤,正如你看到的……)

  1. 「WebKit 在使用相同的方式解析 WebKit。」——實際上,Chrome 是惟一支持多線程 HTML 解析的 port。
  2. 「一旦解析完成,DOM 樹也會構建成相同的樣子。」——實際上 Shadow DOM 只有在 Chromium 才被開啓。因此 DOM 的構造也是不一樣的。自定義元素也是如此。
  3. 「WebKit 爲每一個人建立了‘window’對象和‘document’對象。」——是的,儘管它暴露出的屬性和構造函數能夠經過feature flags來控制。
  4. 「CSS 解析都是相同的。將 CSS 解析爲對象模型是個至關標準的過程。」——不過,Chrome 只支持 -webkit- 前綴,而 Apple 和其餘的 ports 支持遺留的 -khtml- 和 -apple- 前綴。
  5. 「佈局定位?這些是基本生計問題啊」—— 儘管 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 內幕吧。

就在這兒了,小夥子:

擴展閱讀:

JavaScriptHTML5語言 & 開發