Guy Podjarny「HTTP Pipeliningはwebを速くも遅くもしない」
Guy's Pod 2012.6.26のブログエントリ
Guy's Pod » Blog Archive » HTTP Pipelining – Not So Fast…(Nor Slow!)
- http pipeliningサポートが普及した
- でも全然サイト高速化に貢献できてないこと
- なんで速くなってないのか調べた(サイトの作りが効果を相殺してる)
- グラフ入りで詳しく書いてるエントリ
spdyのベンチマークの姉妹編のようなエントリで、http pipeliningとspdyが持てる力を発揮できてない理由は共通してる、など勉強になった
以下斜め読んだ内容
http pipelinig
- 昔から知られた最適化テクニック
- 最近モバイルでもブラウザでも広く使われつつある
- chrome/fxはデフォルト有効になった
http pipeliningで速くなったと期待して軽くテストしてみた
- 全然速くなくてびっくりした
- びっくりしたので本腰入れてテストした
- テストして学んだことをまとめた
いきなりまとめ(時間ない人向け)
- http pipeliningはサイトを高速化しない。が、遅くもしない
- ネットワーク速度、ブラウザ、サイト。色々変えても結論は変わらない
- 効果ゼロな理由は現状のwebサイトの設計の仕方にある
- 読み込むリソースがたくさんのドメインに分散させている
- フロントエンドの設計が筋悪。スクリプトが読込/ブロックしてる状態を放置してる、とか色々
http pipeliningのテスト結果は、自分のspdyのテスト結果にも通じるものあり
- Guy's Pod » Blog Archive » Not as SPDY as You Thought
- Guy Podjarny「SPDYはみんな思ってるものと違う」 - 以下斜め読んだ内容
- spdyが期待されてるほど効果薄い原因と共通してる
テストその1:firefox13。pipelinineオン/オフ。色々なネットワーク環境
- テスト前に思ってたこと
- 遅いネットワーク(レイテンシ高いネットワーク)でpiepeliningは真価を発揮する、はず
- テスト対象。alexaランキングの上位500サイト
- テスト・ツール:WebPageTest
- ブラウザ:Firefox
- 回線速度:DSL、ケーブル、ファイバー。ツールでシミュレート
- レイテンシ:2-4段階で変えた
- 結果
- グラフにした
- x軸:レイテンシ(ミリ秒)
- 読込時間に変化なし:パイプラインon/offで比較して読込時間変化なし
- DSL
- ケーブル
- ファイバー
- pipeliningの実装は複雑
- 概念はシンプルだが実装は大変
- 実装のポイントを前に書いた
- 実装のポイントをおさらい
- サーバ側が実装してるかどうかを検知する仕組み
- サーバの要件
- http/1.1
- keep-alive
- サーバの要件
- 多くのブラウザの挙動
- コネクションの度にpipeliningサポートをチェックする
- リクエスト送ってレスポンスがhttp/1.1かつkeep-aliveかどうかチェックする
- チェックをパスしてからpipeliningオンにしてサーバ通信開始する
- コネクションを作るたびにチェックする
- operaの挙動
- サーバー単位でpipeliningをチェックする
- keep-aliveでレスポンス来たら「pipelinigオンでOK」と判断してpipeliningオンにする
- エラーも増えるが、pipeliningオンにできる場面も増えるアプローチ
- リクエストを分配するモデルをどうするか
- ブラウザが4リクエストを2つのコネクション使って出したいとき、リクエストをどうやってコネクションに割り振るか
- 2つやりかたあり
- 分配してからリクエストを出す
- リクエスト1と2を1つ目のコネクションに割り振り、リクエスト3と4を2つ目のコネクションに割り振ってから通信開始
- 都度リクエストを分配する
- コネクションの上限数に到達してからpipeliningがオンになる
- コネクション1にリクエスト1、コネクション2にリクエスト2を割り振って通信開始
- 開始してから、リクエスト3をコネクション1に、リクエスト4をコネクション3に割り振って、第二弾のリクエストにする
- 去年ブラウザをテストした時。最大コネクション数に達してからpipeliningがオンになる流れ
- サーバ側が実装してるかどうかを検知する仕組み
- fx13の実装
-
- コネクションごとにpipeningサポートをチェック
- 最大コネクション到達を待たずにpipelingスタート
- コネクション1にリクエスト1,2を割り振るやつ
-
- 自分の理想
- サーバ単位でサポートチェック、最大コネクション到達後にpipeliningスタートの組み合わせ
- fxの中の人も自分と同意見になっていった
- fx14でテコ入れ入って、fx16で新しくなった
- fx16
- piepeningの実装は複雑
- 自分た書いた2つのポイント以外の要素も追加されてる
- テストみてもpipeliningの実装として改善してる
- chrome
- pipelingオンはコマンドライン経由
- 実装もfirefoxと違う
- fx13,fx16,chromeでpipeliningのテストした理由
- 実装が異なるから
テストその2:firefox16、chrome
- テスト1と違って1/5の規模でやった。諸事情で
- alexa上位100サイトで実施
- 回線はfiberのみ。上り5Mbps。下り20Mbps
- レイテンシは、300ミリ秒のみ
- 結果はほぼテスト1と同じ
- 平均値と中央値の差分も1-2%以下だから無視できる
- 補足するとfx16はnightlyビルド。なので正式版じゃないのでバグとか機能制限とかあるかも
- pipeliningモデルの実装がfx13とくらべて大きく変わったのは、waterfallの図を見比べれば一目瞭然
- fx16(pipe=オフ)、fx13(pipe=オン)、fx16(pipe=オン)
pipeliningがオンになった頻度
- pipeliningがオンになっててもpipelining通信が発生してるかどうかとは別
- fx13
- 初回12リクエストはpipeliningされなかった
- ドメインあたり13以上リクエストあるときにだけpipelingの恩恵を得る
- テストツール(=webpagetest)はpipeliningと相性悪い
- pipeliningされてリクエストを取りこぼしたりしてる可能性がある
- waterfallの図みても取りこぼしをもいつけることができない
- pipeliningオフの平均リクエスト数のデータと比較してpipeliningされたリクエストの比率を出した
- fx13
- リクエスト数:off=79、on=68
- pipeされたリクエスト数:11。13.9%
- fx16
- リクエスト数:off=78.6、on=65.9
- pipeされたリクエスト数:12.7。16.1%
- chrome
- リクエスト数:off=77.8、on=65
- pipeされたリクエスト数:12.8。16.4%
- 全てのリクエストがpipeliningされてない
- スポットで手動でもテストを行った
テストその3:fx16のbrute foces設定を使う
- fx16,chromeのpipelining実装はとても複雑
- 履歴からpipeliningをオンにしたサーバなのかどうかとかから学習するような機能もある
- fx16のbrute forces設定
- network.http.pipelining.aggressive
- pipelining通信を最大限行う設定で、フォールバック機能付き
- alexa上位100サイトでfx16をbrute force設定で追加でテストしてみた
- 結果は前(brute forceオフ)と大差ない
- pipeliningオフ時と比べると、平均値は3%遅く、中央値は8%遅い
- pipelining利用頻度は35%まで上がった
- brute force設定オンにしてpipelining利用率最大化したら結果
- 却って遅くなったサイトが出てきた
- about.comは2.5倍遅くなった
- WebPagetest - Visual Comparison
- 速くなったサイトもあり、だいたい10-15%高速化
- 却って遅くなったサイトが出てきた
- brute modeオンはまだ適切じゃない
- ブラウザがpipeliningオンにすべきかどうかまで学習できてるわけじゃないから
- 最良の結果が出た所だけとってもpipeliningは1%の高速化にとどまった
なぜ高速化しないか
- ありそうな説明
- 読込が遅いリソースが混じってると、順番待ちしてるリソースの読込がブロックされた状態が長くなる
- 読込が遅いリソースとそうでないリソースを自動判定する仕組みは実現が難しい
- 自分はこれが原因ではないと思ってる
- pipelining機能を活かすようなウェプページになってないのが原因
- 16%のリクエストでしかpipeliningが実際に使われてない
- brute force設定オンでも35%くらい
- リソース別にみると、jsやcssの読込はpipelingほとんどされてない。画像系がpipeliningされてた
- 画像のようなサイズ大のリソースのpipeliningはそれほどインパクト大きくない
- brute force設定オンの時にパフォーマンスが改善したサイトがいくつかあった
- 改善するサイトの数はどんどん増やしていけると思う
- pipeliningが実際に使われる頻度が低い理由
- リソースが多数のドメインに分散しすぎ
- 平均で18ドメイン使ってた
- 各ドメインは1-2リソースしか読み込まれないからpipeliningが利用される機会がない
- フロントエンド実装にボトルネックあり
- cssの@importやjsが他のリソースの読込をブロックしてる状況
- pipeliningはこの状況を改善するものじゃない。引き続きブロックされ続ける
- pipelining実装も万全じゃない
- proxyなどがpipelining通信を邪魔する可能性にブラウザが備えないといけない
- pipeliningが利用可能かどうかをブラウザの検知機能がもっと良くならないといけない
- リソースが多数のドメインに分散しすぎ
まとめ
- 理論上はpipeliningは有益
- webはプロトコルに最適化していく途上
- 現在のサイトは複雑な怪物で、プロキシは役割から外れた振る舞いする
- Subbu Allamarも似たようなこと言ってた
- spdy利用は状況を改善策として指摘できる
- が、指摘したボトルネックへの解決策ではない
- リソースの複数ドメインへの分散や筋の悪いフロントエンド実装は、プロトコルで解決できるものじゃない
- pipeliningの力を存分に引き出すために必要なこと
- 1コネクションで複数ドメインとの通信を多重化
- pipelinng利用できるかどうかをサーバから情報を通知するような仕組み
- ヘッダをうまく使う形になるはず
- mark nottinghamがhintingというスペックのドラフト書いてる。akamaimもいくつかのproposalをhttp/2.0に送った
- draft-nottingham-http-browser-hints-03 - HTTP Browser Hints
- draft-safruti-httpbis-connection-reuse-01 - Connection Reuse for Multiple Hostnames and for Fast Redirect