読者です 読者をやめる 読者になる 読者になる

Gecko勉強会 2で話した内容の補足です

この記事はFirefox Advent Calender 2013の24日目の投稿です。

先日開催されたGecko勉強会 2で「Geckoは何者か Geckoはどこへ行くのか 非同期編」という題で、ブラウザがページを処理するにあたってどのような処理をしているのか、および、ここ数年で直面した課題と対応策について、ざっくりと話させていただきました。

本当は、発表したネタを丸まるここに書くつもりだったんですが、縁あって、勉強会でお話しさせていただいたので、その解説を。

補足解説

ブラウザの処理の詳細について

ブラウザがページを処理するにあたってどのような手続きを踏んでいるのかについては、ブラウザのしくみ: 最新ウェブブラウザの内部構造 - HTML5 Rocks という名記事が存在しています。GeckoWebKitを参照した上で、ブラウザがどのようなプロセスを踏んで処理しているのかについての概説としては、非常によくできているので、一度は読んでおいて損は無いでしょう。

そのような名文ですが、以下の点に注意する必要があります。

  • オーソドックスかつ基本的な内容を網羅しているものの、最新のアーキテクチャについて触れているわけではない
    LayerやCompositor、GPUアクセラレーション、Tiled Renderingなどの「最近の進化」への言及は殆ど存在しません。記事が公開されたタイミングが2011年8月と古いので致し方ない点も有りますが、こうした点については、(主に英語で書かれた)他の情報を参照する必要が有ります。
  • JavaScriptエンジンの進化については書かれていない
    これも厄介な点です。HTMLおよびCSSというレンダリングエンジンとして重要な構成要素については詳細に書かれていますが、JSエンジンの進化の歴史については、別途情報を参照する必要が有ります。
  • なぜこのような設計になっているのかについての言及が少ない
    具体的には、ブラウザエンジンがシングルスレッドな理由について、思いのほかさらりと流されている点です。この点については、JSがシングルスレッドで実行される同期実行モデルであることと、CSSOMを介したレイアウト情報の取得がJS側から可能である事に起因した設計です(とはいえ、鶏と卵の関係のような物で、シングルスレッドの同期実行モデルであったが故にレイアウト情報の取得が同期的に可能であり、同時に、そのようにレイアウト情報が同期的に取得できるような世界になってしまったが故、このような設計が続いているとも言えます)。

とはいえ、オーバービューとしては非常に出来が良いため、目次と第二章まで流し読みをして、その後、必要に応じて読み返すような読み方がおすすめです。

ブラウザの処理の詳細について2

実際にはブラウザの処理というのは、スライド中の図のようには上手く行きません。DOMツリーの精製中にdocument.writeなどが走り、パースに対して影響を与える事が有るなどもありますので、目安という事で。

Mozilla Memes

Mozillaの開発IRCなどで流れたジョークをアメリカンな画像にして乗っけてるジョーク置き場です。基本的にハイコンテクストです。繰り返しますが、ハイコンテクストです。

ちなみにTwitterアカウントもあります。最近はあんまり更新されないね (´・ω・`)

CompositorとLayer

ブラウザのレンダリング処理に際し、CSSのposition:absolute, fixed, CSS Animation, CSS Tranformなどは、基本的には再度ペイントを行わずにページ上のどこに重ね合わせるかを判断するだけで、最終的なレンダリング結果を出力できます。この処理のことをCompositionと言います。そして、その合成にあたっての要素の重なり合わせに用いられる物がLayerです。まんまPhotoshopのLayer。

このLayerについては、他にも、Pluginの描画対象の要素だったり、WebGLなどが該当します。これらの処理は、そこ自体が独立した描画コンテクストを保有している為、要素の中で描画されている物が、レイアウトフローに影響を与える事がないため合成が可能というわけです。

なお、LayerとCompositionの仕組みはGeckoに限らず、WebKit, Blink, トレンドを鑑みるにおそらくIE (Trident)も実装していますが、仕様などで明文化された挙動ではなく、仕様の重箱の隅をつついた最適化であるため、実装依存となります。速度を突き詰めると概ね似たような設計にはなってきていますが、あくまでも実装依存ですので、細部の挙動はブラウザ間およびバージョン間で違いが有る点に注意しましょう。

Off Main Threadを説明した画像の出典

http://benoitgirard.wordpress.com/2012/05/15/off-main-thread-compositing-omtc-and-why-it-matters/

Firefox Android (Fennec, Native Fennec)のUIスレッドとコンテンツスレッドの分離

これは、正確には「Javaで書かれたUIスレッドとGecko上で動くスレッドの分離」です。そして、Fennecでは、UIロジックの一部がGeckoスレッド上で動作している為、完全に、UIスレッドとコンテンツスレッドを分離しているわけではありません。とはいえ、Off Main Thread Compositiingの実装によってユーザーとの入出力を受け取るスレッドが分離されており、Geckoスレッド上で記述されるロジックもそれほど巨大な物ではない為、結果として、軽快なレスポンスを実現できています。

プロセス分離

プロセス分離は、あくまでも、レンダリングエンジンのスレッド(プロセス)をUI側と切り離す事でコンテンツ側のハングアップをUI側に影響させないためのアプローチです。レンダリングエンジンのシングルスレッドのループについては、問題を解決できていません。レンダリング部分の設計転換が歴史的にも困難である事と、コンテンツ側の影響でUIが止まってしまう問題に比べれば相対的に問題ではないため迅速な解決が必要ではないことが、先送りとなっている理由です。

宣伝

この辺りの話について、偶然にも、冬コミで頒布予定のRustの薄い本である「Rust Dojo」のServoの章で説明しています。興味を持たれた方がいらっしゃいましたら、足を運んでいただければ幸いです。