開發者需要了解的WebKit

infoq發表於2013-03-22

  Paul Irish是著名的前端開發工程師,同時他也是Chrome開發者關係團隊成員,jQuery團隊成員,Modernizr、 Yeoman、CSS3 Please和HTML5 Boilerplate的lead developer。針對大家對WebKit的種種誤解,他在自己的部落格發表了《WebKit for Developers》一文,試圖為大家解惑。

  對許多開發者來說,WebKit就像一個黑盒。我們把HTML、CSS、JS和其他一大堆東西丟進去,然後WebKit魔法般的以某種方式把一個看起來不錯的網頁展現給我們。但事實上,Paul的同事Ilya Grigorik說:

WebKit才不是個黑盒。它是個白盒。並且,它是個開啟的白盒。

  所以讓我們來花些時間瞭解這些事兒:

  • 什麼是WebKit?
  • 什麼不是WebKit?
  • 基於WebKit的瀏覽器是如何使用WebKit的?
  • 為什麼又有不同的WebKit?

  現在,特別是Opera宣佈將瀏覽器引擎轉換為WebKit之後,我們有很多使用WebKit的瀏覽器,但是我們很難去界定它們有哪些相同與不同。下面我爭取為這個謎團做些解讀。而你也將會更懂得判斷瀏覽器的不同,瞭解如何在正確的地方報告bug,還會了解如何在特定瀏覽器下高效開發。

  標準Web瀏覽器元件

  讓我們列舉一些現代瀏覽器的元件:

  • 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內幕吧。

  就在這兒了,小夥子:

相關文章