Facebook の BigPipe と TTI 01:59

Posted at 2010/10/22 01:59, Modified at 2010/10/22 03:42

Facebook のフロントエンドは結構かわったことをやっていて、例えば、ログイン後の http://www.facebook.com/home.php には

<div id="pagelet_home_stream"></div>

みたいな空の HTML があり、その後に

<script>big_pipe.onPageletArrive({ … });</script>
<script>big_pipe.onPageletArrive({ … });</script>
...

と script 要素が何個もならんでいる。

BigPipe: Pipelining web pages for high performance

この仕組みは (変数名のとおり) BigPipe と呼ばれていて、彼ら自身が BigPipe: Pipelining web pages for high performance で解説している。

かいつまんで説明しよう。通常、Web ページというのは

  • ブラウザが http://example.com/foobar を要求する
  • example.com のサーバーが /foobar にあるページを作るべく、MySQL などに問い合わせて、最終的には HTML にして送る
  • ブラウザが送られてきた HTML をレンダリングする

といった感じでユーザーに届く。さてここで、サーバーが MySQL などに問い合わせている間、ブラウザは何をしているんだろうか。なにもしていない。ここではサーバーがボトルネックになっている。一方で、レンダリングがはじまると今度はブラウザがボトルネックになる。

サーバーの忙しさとブラウザの暇さ、あるいはその逆を (CPU の命令パイプラインのように) オーバーラップさせて全体の効率をあげる、というのが BigPipe の核となるアイデアだ。

image:1:1287680982-bigpipe.png

実際の実装は

  • サーバーは HTML の外枠を送信したら、一回ソケットを flush して
  • ブラウザはそれをレンダリングして、BigPipe の JavaScript を読み込む
  • サーバーは「友達リスト」や「更新情報」といった個々の部品 (BigPipe ではこれを "pagelet" と呼ぶ) をひとつづつ
    • HTML まで作り、完成するごとに script 要素につめてブラウザに送信して、また flush し
    • ブラウザは受信するごとに script 要素を実行し、既存の外枠の innerHTML に HTML をさしこんだり、CSS や画像、JavaScript のダウンロードをはじめる
  • こうして、サーバーが最初の HTML をすべて送信し終わったときには、ブラウザ側のレンダリングもそれなりに終わっている

といった感じに動作する。iframe と multipart が合体したような感じ、という説明はわかりやすいんだかどうだか。

TTI: Time-to-Interact

Facebook が目指している「速さ」と、いままで Web ページで測っていた「速さ」には、ちょっと差がある。いままでは「ページの読み込み開始からレンダリング完了までに経過する時間」をいかに短くするかが勝負だったと思う。しかし、Facebook は「ページの読み込み開始から、ページ上でもっとも重要な部分が表示され、利用可能になるまで」というレンダリング途中の感覚値としての速さについても、考慮にいれている。

彼らは Making Facebook 2x Faster でそれを TTI (Time-to-Interact) と呼んでいる。

We call this metric Time-to-Interact (TTI for short), and it is our best sense of how long the user has to wait for the important contents of a page to become visible and usable. On our homepage, for example, TTI measures the time it takes for the newsfeed to become visible.

いまどきの読み込み時間は、YSlow や Page Speed で簡単に測れるし、内訳をもとに点数も出してくれる。ついその数字を追ってしまうのは人の性だ。そんななかで

  • それも大事だけど、この部分をこうすると UX 改善するんじゃないか、と問題を再定義して
  • JavaScript でこういうふうにやれば TTI 短くなって UX 良くなるよね、と実装して
  • JavaScript がオフでもそれなりに動くようにして (BigPipe が JSON ではなく HTML を返しているのは、このため + DOM が遅いから、だと思う)
  • 本番に投入して
  • Facebook のあらゆるページで使えるようにして (たとえば、リクルートと提携して出来たという コネクションサーチ も BigPipe を使っている)

と、全部やっていくのを考えると、これはもう、アメリカの回線が遅いからとか、開発者の数が多いからとか、そういう問題じゃないなあと思いました。

0 comments
riddle for guest comment authorization:
Where is the capital city of Japan? ...

blog.8-p.info加藤和良 の個人的なブログで、プログラミングのはなしが多めです。