開発者のための WebKit

このノートは、Paul Irishによる記事 “WebKit for Developers” の日本語訳です。


WebKit box logo 僕ら開発者の多くにとって、WebKit はブラックボックスだ。HTML, CSS, JS, その他のアセットを投げると、WebKit は魔法でもかけたかのように、綺麗な Web ページを返してくれる。しかし、僕の同僚 Ilya Grigorik は本当の WebKit はこうだと言っている

WebKit はブラックボックスではない。ホワイトボックスなんだ。さらにそれだけではなく、オープンなホワイトボックスなんだ。

じゃあ、これから次のことについて理解していこう。

WebKit ってなに?
なにが WebKit じゃないの?
WebKit ベースのブラウザで WebKit はどう使われているの?
なんですべての WebKit が同じじゃないの?

さて、世の中に数多くの WebKit ブラウザがあふれるようになった。とくに Opera が WebKit に移行したなんて話も新しい。ただ、それぞれの WebKit のどこが共通で、どこが違うのかを知るのはとても難しい。これからする説明で、それが少し分かるようになるだろう。そうなれば、ブラウザの違いについて今まで以上によく分かるし、適切なバグトラッカーに報告できるようにもなる。さらに特定のブラウザに対し、どうやって今まで以上に効果的に開発できるかを理解できるだろう。

標準的な Web ブラウザのコンポーネント

今日のブラウザは、いくつかのコンポーネントから成り立っている。

WebKit ベースのブラウザ間で、このうちどれが共通だろう?ほとんどの場合において、最初の2つだけだ

他のコンポーネントは、個々の WebKit port 側で扱われる。じゃあ、port って何だろう。

WebKit port とは

WebKit には異なる “port” がある。ここでは Sencha の エンジニアリングディレクターで WebKit ハッカーの Ariya Hidayat に説明してもらおう

WebKit としてよく紹介されるのが、Mac OS X 上で動作する Apple の WebKit だ(これは最初の、つまりオリジナルな WebKit ライブラリだ)。そこから想像できる通り、この WebKit 上の様々なインターフェースは、Mac OS X 上の異なるネイティブライブラリを利用し実装されている(ほとんどの場合 CoreFoundation が中心だ)。たとえば、色のついたフラットなボタンに角丸を指定したとしよう。WebKit はどこから、そしてどのようにボタンを描画するかを知っている。しかし、最後のボタンの描画作業(ユーザのモニタ上に pixel でボタンを描くこと)は CoreGraphics の仕事になる。

ここで説明されている通り、CG は Mac port 特有の例だ。Mac の Chrome はこの場合 Skia を使う。

時が経ち、WebKit はデスクトップ、モバイル含め異なるプラットフォームに “port”(移植)された。これらは多くの場合 “WebKit port” と呼ばれる。Apple 自身も Windows 版の Safari の開発にあたり WebKit を移植し、Windows 上で動作するようにした。ここでは CoreFoundation ライブラリの Windows 版(限定的な実装)を利用した。

…でも、Windows 版 Safari は終わっちゃったけれど。

それ以外にも、多くの “port” が存在している(一覧をご覧あれ)。Google は Chromium port を開発し運用している。Gtk+ を元にした WebKitGtk というものもある。Nokia(が買収した Trolltech)は WebKit の Qt port を運用しており、とくに QtWebKit module として知られている。

代表的な WebKit port

port が独自のフォーカスを持つこともある。Mac port はブラウザと OS の分離にフォーカスし、そこに Obj-C と C++ バインディングを用意することで、レンダラをネイティブアプリに埋め込むことを可能にしている。Chromium のフォーカスは純粋にブラウザだ。QtWebKit はクロスプラットフォームな GUI アプリケーションアーキテクチャの中で、そのランタイム、もしくはレンダリングエンジンを提供するために port を提供している。

すべての WebKit ブラウザで共通なもの

まず、すべての WebKit port で共有されている機能をおさらいしよう。

  1. まず、WebKit は HTML を同じやり方でパースする。 ※ ただし threaded HTML parsing を有効にした WebKit port(現時点では Chromium のみ)を除く。
  2. うん……。で、パースが終わったら、DOM ツリーは同じように構築される。 ※ ただし Shadow DOM が 有効にされた port(現時点では Chromium のみ)を除く。なので DOM 構築も異なる。カスタム要素についても同じことが言える。
  3. ええと……。あ、WebKit はどの port でも window オブジェクトと document オブジェクトを生成する。 ※ ただしそれらのプロパティやコンストラクタは feature flag の有効度合いによって異なる。
  4. そうだね……。でも CSS パースは同じだ。CSS コードをズズッとすすって CSSOM にする。この方法はもうスタンダードだ。 ※ ただし Chrome は -webkit- 接頭辞のみをサポートするが、Apple や他の port は古い -khtml-, -apple- もサポートするという違いがある。
  5. ……。レイアウトとか…ポジショニングはどうかな?パンにバターみたいな組み合わせなんだし、どこでも同じだろう?ね! ※ ただしサブピクセルレイアウト、飽和レイアウト演算は WebKit の一部にもかかわらず port ごとに違う。
  6. だって。すごい。

というわけで、とても複雑だ。

FlickrGithub が機能を有効フラグ付きで実装しているように、WebKit でも同じ事をしている。これによって port が WebKit のコンパイルタイム Feature Flag を使い、機能を有効・無効にできるようになっている。機能はランタイム flag として現れることもある。この場合はコマンドラインスイッチ(これは Chromium のもの)about:flags みたいな設定から有効・無効にできる。

じゃあ、今度こそ WebKit で何が共通なのかまとめてみよう……

WebKit port 間で共通なもの

すこしぼやけてきたので、共通でないものを挙げてみよう。こちらはそれほどぼやけていない。

WebKit port 間で共通ではないもの

ひとつ紹介しよう。2D 描画 では、port ごとにまったく異なるライブラリを使用し、スクリーンへの描画処理を行なっている。

WebKit のグラフィックスレイヤー

細かいところで言えば、最近実装された機能 CSS.supports() は win port と wincairo port 以外で有効にされている。これは、これら2つの port で CSS3 Conditional の機能が有効にされていないからだ。

ちょっと技術的な感じになってきたから、ちょっと細かいところをつつこうか。いま説明したことも、厳密には正しくない。共有されているものは、実際には WebCore なんだ。WebCore はレイアウト、レンダリング、HTML と SVG の DOM ライブラリで、みんなが “WebKit” と呼んでるものは基本的にこいつだ。では実際の “WebKit” は何かというと、WebCore と port のバインディングレイヤーを指す。まあ、ふつうの会話であればこの違いなんて、ほとんどどうでもいいんだけれど。

図で説明すると分かるかな。

WebKit Diagram

WebKit 中の多くのコンポーネントが交換できるようになっている(灰色のところね)。

たとえば、WebKit の JavaScript エンジン JavaScriptCore。これは WebKit のデフォルトのエンジン(WebKit が KHTML を fork しスタートした際は、KDE の KJS をベースにしていた)。いっぽう、Chromium port では V8 に置き換わっており、さらに固有の DOM バインディングでマップしている。

フォントやテキストの描画はプラットフォームのとても大きな部分だ。WebKit は Fast path, Complex path という2つの text path を持っている。どちらもプラットフォーム固有(ポート側の)サポートを必要とするけれど、Fast path はただどのようにグリフをブリットするかを知るだけでよい(WebKit はそれをプラットフォームのためにキャッシュする)のに対して、Complex path は実際に全文字列をプラットフォームレイヤーに渡して「描画してくれ」と伝える。

WebKit はサンドウィッチのようなものだ。しかし Chromium においてはタコスに近い。そう、美味しい Web プラットフォームのタコスなのだ。 Dimitri Glazkov, Chrome WebKit hacker. Champion of Web Components and Shadow DOM

じゃあ、すこし広いところ、いくつかの port とサブシステムを見てみよう。次の表は5つの WebKit port についてまとめたものだ。WebCore の多くを共有していても、スタックが多種多様なことが分かるだろう。

Chrome (OS X) Safari (OS X) QtWebKit Android Browser Chrome for iOS
レンダリング Skia CoreGraphics QtGui Android stack/Skia CoreGraphics
ネットワーク Chromium network stack CFNetwork QtNetwork Chromium network stack の fork Chromium stack
フォント CoreText via Skia CoreText Qt 内部のもの Android stack CoreText
JavaScript V8 JavaScriptCore JSC (V8 は Qt のその他で利用) V8 JavaScriptCore (JIT 無し) *

* Chrome for iOS についての補足をしよう。分かってると思うけど、こいつは UIWebView を使っている。だから UIWebView が提供するもの、つまり Mobile Safari と同じレンダリングレイヤー、V8 ではなくて JavaScriptCore, そしてシングルプロセスモデルしか利用できない。しかし、ネットワークレイヤー、同期やブックマークのインフラ、Omnibox, メトリクスやクラッシュレポートなど、Chromium 側のコードもかなり利用している。(また、個人的な意見だけど、JavaScript がモバイルでボトルネックになることは非常に稀なので、JIT コンパイラが無いことのインパクトは限りなく小さいだろう。)

わかった。それでどうなるの?

WebKit がそれぞれ違うのがわかって怖いよー

大丈夫!WebKit の layoutTest がカバーする範囲はとても広い(最後に見た時点で 28,000 以上)。テストは既存の機能に関するものだけじゃなくて、見つかったリグレッションについても用意されている。新しい、もしくは難解な DOM/CSS/HTML5 系の機能について調べるとき、layoutTest が小さくまとまったすばらしいデモになってることが多いんだ。

さらに、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 で使えるようになる。

もうひとつ言いたいこと。Chromium を採用するのは すべての Opera ブラウザだ。だから Windows 版 Opera, Mac 版 Opera, Linux 版 Opera, Opera Mobile が Chromium ベースになる。さらにはシンクライアントの Opera Mini も、いまの Presto ベースなサーバサイドレンダリングファームを Chromium ベースに変更するんだ。

んーと、WebKit Nightly ってなに?

WebKit Nightly は Mac port の WebKit で、Safari が使うバイナリの中で動作する(ただ、内部のライブラリがいくつか差し替わってはいる)。だから WebKit Nightly の挙動や搭載している機能は将来の Safari と一緒だ。ざっくりと言えば、WebKit Nightly と Safari の関係は、Chromium と Chrome のそれみたいなものかな。

Chrome Canary も、ここ1, 2日の最新の WebKit ソースを使っている。

WebKit の中身についてもっと教えてよ!

ほーらよ、相棒!

あわせて読みたい

この記事で WebKit ブラウザの内部について説明でき、またどこからどこまでを WebKit, どこからどこまでが WebKit port なのかを伝えられたら嬉しい。


Reviewed by Peter Beverloo (Chrome), Eric Seidel (WebKit).
I’ll update with any corrections or modifications.