Webkit入門開胃菜
對(duì)于許多開發(fā)者而言,WebKit 是一個(gè)黑盒子。我們把 HTML, CSS, JS 和一堆資源放進(jìn)去,然后 WebKit 以某種方式,奇妙地變出一個(gè)中看又中用「美觀而實(shí)用」的網(wǎng)頁。事實(shí)上,如同我同事 Ilya Grigorik 所說 …
WebKit 它不是一個(gè)黑盒子,而是一個(gè)白盒子,并且是一個(gè)開放的白盒子。
那么讓我們花一點(diǎn)時(shí)間來理清一些東西:
- WebKit 是什么?
- WebKit 不是什么?
基于 WebKit 的瀏覽器使如何運(yùn)用 WebKit ?
為什么所有的 WebKit 并不一樣「呢」?
雖然現(xiàn)在我們已經(jīng)有了很多 Webkit 瀏覽器了,特別是有消息稱 Opera 也已經(jīng)轉(zhuǎn)移到 WebKit 了,但是想要理解他們的相同點(diǎn)和不同點(diǎn)還是挺難的。下面我將側(cè)重講這方面,你將能更好的分辨瀏覽器的差異,在合適的 bug 跟蹤系統(tǒng)提交 bug,并了解如何更加高效的針對(duì)特定的瀏覽器進(jìn)行開發(fā)。 標(biāo)準(zhǔn)的 Web 瀏覽器組件 讓我們看一下現(xiàn)代 web 瀏覽器的幾個(gè)組件:
- 解析(HTML, XML, CSS, JavaScript)
- 排版(Layout)
- 文字和圖像渲染
- 圖像解碼
- GPU 交互
- 網(wǎng)絡(luò)接入
- 硬件加速
那么哪些是基于 WebKit 的瀏覽器所共享的呢? 幾乎只有前兩項(xiàng)。
其它的由各自的 WebKit port 負(fù)責(zé)。讓我們回顧下這意味著什么? WebKit Port 雖然 Webkit 有不同的 ”port”,但請(qǐng)?jiān)试S我引用來自 Sencha 的 WebKit hacker 兼 eng 主管— Ariya Hidayat 解釋一下 :
WebKit 最常見的參考實(shí)現(xiàn)是 Apple 自己的運(yùn)行在 Mac OS X 上的WebKit 實(shí)現(xiàn)(這也是最早最原始的 WebKit 庫)。正如你所知,在 Mac OS X 上各種接口的實(shí)現(xiàn)使用不同的本地庫,大多集中在 CoreFoundation 。比如,你定義了一個(gè)帶有特別的圓角的平面彩色按鈕,那么 WebKit 會(huì)知道在哪里以及如何畫繪制這個(gè)按鈕??墒?,最終實(shí)際畫繪制按鈕的職責(zé)(作為用戶顯示器上的像素)還是落到了 CoreGraphics 身上。
如上所述,只有 Apple 自己在 Mac 上的實(shí)現(xiàn)是使用 CG。Chrome 在 Mac 上的實(shí)現(xiàn)使用的是 Skia。
隨著時(shí)間推移,WebKit 被移植到不同的平臺(tái),包括桌面和移動(dòng)端。這種做法通常被稱作“一個(gè) WebKit port”。對(duì)于 Safari 瀏覽器的 Windows 版本,Apple 也把自己的 WebKit 移植到 Windows 上,同時(shí)使用 Windows 版(閹割版)的 CoreFoundation 庫。
盡管 Windows 版 Safari 現(xiàn)在掛了 。
此外,還有許多其他的”port”(查看全部的列表)。Google 創(chuàng)建了一個(gè)持續(xù)維護(hù)的 Chromium port。還有,這是基于 GTK + 的 WebKitGtk。Nokia(通過它收購的 Trolltech 公司)維護(hù) Qt 的 WebKit 移植版本,一般叫做QtWebKit 模塊。(譯者注:后來又便宜賣了,現(xiàn)在 Qt 屬于 Digia 公司)
一些 WebKit port
- Safari
- OS X 版和 Windows 版的 Safari 是兩個(gè)不同的 port
- 用于 Safari 的 WebKit nightly 將會(huì)慢慢成為一個(gè)邊緣化的版本……
- Mobile Safari
- 一開始在內(nèi)部的私有分支上維護(hù),不過最近代碼也合并回主干(being upstreamed)。(譯者注:upstream 是開源項(xiàng)目的術(shù)語,指其它人或者公司從主干代碼開出來的私有分支的代碼重新提交回主干)
- iOS 版的 Chrome(使用 Apple 的 WebView;后面有更多關(guān)于它的不同之處)
- Chrome (Chromium)
- 安卓版 Chrome (直接使用 Chromium port)
- Chromium 也驅(qū)動(dòng) Yandex 瀏覽器 ,360 瀏覽器 ,搜狗瀏覽器 (譯者注:其實(shí)國內(nèi)的殼瀏覽器太多了,你懂的)等,以及將來的 Opera。
- Android 瀏覽器
- 使用目前最新的 WebKit 代碼
- 還有很多 port :Amazon Silk(亞馬遜 Silk 瀏覽器), Dolphin(海豚瀏覽器),Blackberry(黑莓瀏覽器),QtWebKit,WebKitGTK+,EFL port (Tizen),wxWebKit,WebKitWinCE 等等。
不同的 port 可以有不同的側(cè)重點(diǎn)。Mac port 關(guān)注的是瀏覽器內(nèi)核和操作系統(tǒng)相關(guān)的實(shí)現(xiàn)部分的分離,它通過 Obj-C 和 C++ 代碼把(WebKit)渲染引擎嵌入到本地應(yīng)用中。 Chromium 則更多關(guān)注瀏覽器本身。而 QtWebKit 則把它的 WebKit 實(shí)現(xiàn)作為一個(gè)運(yùn)行時(shí)的庫或者渲染引擎,同其跨平臺(tái) GUI 應(yīng)用程序框架一起提供給其它應(yīng)用使用。
哪些是所有 WebKit 瀏覽器所共享的?
首先,讓我們回顧一下所有 WebKit port 的共同點(diǎn)。
這很有趣,我試著寫了幾次。每次都會(huì)被 Chrome 團(tuán)隊(duì)成員斧正,正如你將會(huì)看到的……
1. 首先,WebKit 以同樣的方式解析 HTML 。好吧,除了 Chromium,它是迄今為止唯一支持 threaded HTML 解析的 port(譯者注:Last week in WebKit: Threaded HTML parser and background blending)。
2.然而一經(jīng)解析,DOM 樹構(gòu)造依然相同。所以,實(shí)際上只有在 Chromium port 中 Shadow DOM 被打開的情況下, DOM 結(jié)構(gòu)才會(huì)改變。當(dāng)然這同樣適用于自定義元素。
3. WebKit 都會(huì)創(chuàng)建了一個(gè) window 對(duì)象和 document 對(duì)象。使得通過它暴露出來的屬性和構(gòu)造器(譯者注:某種函數(shù))可以在 feature flags 選擇打開。
4.CSS解析基本是一樣的,把你的 CSS 文件解析成(內(nèi)部的)CSS 對(duì)象模式還是一個(gè)比較標(biāo)準(zhǔn)的過程。是的,盡管 Chrome 僅接受 -webkit- 前綴,然而 Apple 和其它的 port 接受遺留前綴像 -khtml- 和 -apple-。
5.排版,定位?好吧,也來點(diǎn)面包和黃油吧!Sub-pixel layout 和 saturated layout (譯者注:已經(jīng)添加鏈接)算法是 WebKit 的一部分,但是各 port 之間存在差異。
6. 好極了。
所以,事情很復(fù)雜。
就像 Flickr 和 Github 通過 flags 標(biāo)識(shí)實(shí)現(xiàn)特性,WebKit 也是這么做的。允許 port 通過 WebKit 的編譯特性標(biāo)識(shí) , 啟用或禁用各種功能。這些特性可以作為運(yùn)行時(shí)標(biāo)識(shí)被暴露,也可以通過命令行開關(guān)(Chromium 是這樣) ,或者通過配置 about:flags 。
好吧,讓我們重新歸納下各 WebKit 的共同點(diǎn)……
WebKit port 的共同點(diǎn)
- DOM,window, document
- 大致相同
- CSSOM
- CSS 解析,屬性/值處理
- 無供應(yīng)商前綴處理
- HTML 解析和 DOM 結(jié)構(gòu)
- 如果我們只考慮 Web 組件,它是相同的
- 所有的布局和定位
- Flexbox,浮動(dòng),塊級(jí)格式化上下文… 所有這些是共享的
- Chrome DevTools ( WebKit Inspector) 的 UI 和各種工具
- 盡管去年4月以來,Safari 為 Safari Inspector 放棄了自有的非 Webkit 的閉源 UI
- contenteditable, pushState,F(xiàn)ile API,大部分的 SVG,CSS Transform 公式, Web Audio API,localStorage
- 特性盡管后端不同。每一個(gè) port 的 localStorage 可能使用不同的存儲(chǔ)層,Web Audio API 可能使用不同的 audio API
- 大量其它的特性和功能
哪些是 WebKit port 不共享的
- 運(yùn)行在 GPU 上的
- 3D變換
- WebGL
- 視頻解碼
- 屏幕上的 2D 繪圖
- 抗鋸齒方法
- SVG & CSS 漸變渲染
- 文字渲染&斷字
- 網(wǎng)絡(luò)堆棧(SPDY,預(yù)渲染,WebSocket 傳輸)
- JavaScript 引擎
- JavaScriptCore 在 WebKit repo. 它和 V8 綁定在 WebKit 里
- 表單控件渲染
- <video> & <audio> 元素行為(以及編解碼器支持)
- 圖像解碼
- 導(dǎo)航 前進(jìn)/后退
- pushState() 的導(dǎo)航部分
- SSL 特性像嚴(yán)格傳輸安全性(Strict Transport Security)和公鑰
看下面這些: 2D 圖形方面依賴于不同的 port ,我們用完全不同的庫把它繪制到屏幕上:
或者更微觀一點(diǎn),最近的新特性:CSS.supports() 除了 win 和 wincairo, 所有的 port 都可用 ,同時(shí)它們沒有啟用 css3 conditional (css3 特性檢測(cè))特性。
既然我們了解了這些,是時(shí)候更加深入一些了。事實(shí)上以上的敘述是不正確的。 WebCore 是共享的,WebCore 是一個(gè)針對(duì) HTML 和 SVG 的排版、渲染和文檔對(duì)象模型(DOM)的庫,它就是人們通常所說的 WebKit 。實(shí)際上“WebKit ”是 WebCore 和 port 的綁定層,盡管在扯淡時(shí)這種區(qū)別是不重要的。
下圖應(yīng)該有所幫助:
WebKit 里面許多的組件是可交換的(上圖灰色區(qū)域)。
舉個(gè)例子,起初,WebKit 的默認(rèn) JavaScript 引擎是 JavaScriptCore 。(它基于最初的 KJS (源于 KDE),WebKit 開始只是 KHTML 的一個(gè) fork 分支)。后來,Chromium port 替換為 V8,然后使用獨(dú)立的 DOM 綁定機(jī)制映射上去就完事了。
字體和文本渲染占一個(gè)平臺(tái)的很大一部分。WebKit 有2個(gè)單獨(dú)的文本路徑:快速(Fast)和復(fù)雜(Complex)。兩者都需要平臺(tái)特定(port-side)的支持,但快速僅需要知道如何 blit glyphs (傳輸符號(hào))(WebKit 為平臺(tái)做了緩存),復(fù)雜確實(shí)需要轉(zhuǎn)換整個(gè)字符串到平臺(tái)層然后說“請(qǐng)繪制這個(gè)”。
WebKit 像一個(gè)三明治。盡管在 Chromium 中更像墨西哥玉米卷。一個(gè)美味的 web 平臺(tái)玉米卷。”——Dimitri Glazkov,Chrome WebKit hacker,Web 組件和 Shadow DOM 的擁護(hù)者。
現(xiàn)在,讓我們放大鏡頭看看一些 port 和一些子系統(tǒng)。下面是 WebKit 的5個(gè) port;盡管它們共享WebCore 的大部分,但它們的 stacks 是不同的。
* iOS 版 Chrome 注解:你可能知道它使用 UIWebView,由于 UIWebView 的能力意味著它只能使用像移動(dòng)版 Safari 那樣的渲染層,JavaScriptCore (替代 V8),單進(jìn)程模式。盡管如此,大量的 Chromium 代碼起銜接作用 ,例如網(wǎng)絡(luò)層,同步和書簽基礎(chǔ)設(shè)施,地址欄,度量和崩潰報(bào)告。(同時(shí),更重要的是,JavaScript 很少成為移動(dòng)端的瓶頸,缺乏 JIT 編譯器(譯者注:詳細(xì)資料)只有很小的影響。)
好吧,那么我們?cè)撛趺崔k? 現(xiàn)在所有 WebKit 完全不同了,我弱弱的表示害怕。
沒必要!WebKit 的 layoutTests 覆蓋面非常廣(最新統(tǒng)計(jì)是28,000 個(gè) layoutTests),不僅針對(duì)已存在的特性,而且針對(duì)任何發(fā)現(xiàn)的回歸。實(shí)際上,每當(dāng)你探索一些新的或難懂的 DOM/CSS/HTML5 特性時(shí),layoutTests 常常已經(jīng)有了奇妙的最小化的示例。
此外,W3C 正在努力研究一致性測(cè)試套件 。這意味著我們可以期待不同的 WebKit port 和所有瀏覽器使用同樣的測(cè)試套件測(cè)試,帶來更少的怪癖模式和更彼此協(xié)作的網(wǎng)絡(luò)。所有參加過 Test The Web Forward 大會(huì)(譯者注:比如去年在北京的分會(huì)場(chǎng)) 為此做出努力的人們,謝謝你們。
Opera 剛剛轉(zhuǎn)移到 WebKit了。有何影響呢?
Robert Nyman 和 Rob Hawkes 也談到了這個(gè) ,但是我將補(bǔ)充一些:Opera 公告的一個(gè)明顯的部分是 Opera 將采用 Chromium。這意味著 WebGL,Canvas,HTML5 表單,2D 圖像實(shí)現(xiàn)——所有這些 Chrome 和 Opera 將保持一致。同樣的 APIs,同樣的后端實(shí)現(xiàn)。由于 Opera 是基于 Chromium,你可以深感自信,你未來的工作可以同時(shí)兼容 Chrome 和 Opera 。
我也應(yīng)該指出所有的 Opera 瀏覽器 將采用 Chromium。因此 Windows,Mac 和 Linux 版 Opera,以及 Opera Mobile(完全成熟的移動(dòng)瀏覽器)。甚至 Opera Mini 輕客戶端,將使用基于 Chromium 的渲染替換當(dāng)前的基于 Presto 的服務(wù)器端渲染。
WebKit Nightly,是什么?
它是 WebKit 的一個(gè) mac port ,內(nèi)部運(yùn)行跟 Safari 一樣的二進(jìn)制文件(盡管會(huì)替換一些底層庫)。因此它的行為和特性跟 Safari 全一樣。如果你想回到從前,可以考慮它……總之,WebKit Nightly 面向 Safari , Chromium 面向 Chrome 。 Chrome Canary 包含最進(jìn)一兩天之內(nèi)的 WebKit 資源。
告訴我更多 WebKit 的內(nèi)幕。
你已經(jīng)得到了,同學(xué)。
【關(guān)于本文】本文涉及到非常多的專業(yè)術(shù)語,為了讓大家第一時(shí)間更好的品嘗這道大菜,一絲特別邀請(qǐng)了幾位 Webkit 專業(yè)開發(fā)人士作為本文的翻譯顧問,在此表示由衷的感謝!翻譯不當(dāng)之處,歡迎批評(píng)指正。