HTTP/2 勉強会 #7 で発表しました
先週の木曜日の話になりますが、HTTP/2 勉強会 #7 で発表してきました。今回は「パフォーマンス」がテーマということだったので、HTTP/2 の優先度についてを中心に話をしてきました。発表に使った資料は以下を参照してください。
そもそもなんで今さら優先度の話なのか、ということなんですが、その理由は前回開催された LT 大会まで遡ります。前回の LT 大会では「Above the Fold のリソースをサーバープッシュすればレンダリングが速くなるのでは?」という仮定を元に検証をした話を LT しました。その時の資料は以下を参照してください。
この時は、HTTP/2 の優先度が最適化されていない Chrome を使ったりと検証方法が悪かったりもしたのですが、検証の過程でサーバープッシュが他のリソースの読み込みを遅延させる場合がある、ということは分かっていました。リソースが遅延する理由はおそらく優先度が大きく関連しているであろう、という予想があったので、今回は優先度の理解を深めるための話をしたのでした。
発表資料を見てもらえると分かるかと思いますが、現状、各ブラウザは HTTP/2 の優先度については異なる戦略をとっています。Firefox は優先度ツリーを構成する、Chrome は依存関係を使わない単純なツリーを構成する、Edge は優先度を使わない、といった状況です。発表後に大津さんからフィードバック (いつもありがとうございます!) をいただいたところによると、Chrome は SPDY の優先度をマッピングしている状態であり、Blink の実装上の制約もあって今のような状態になっているそうです。もしかすると SPDY が死ぬ頃には改善が入ったりするのかもしれませんね。
発表では、サーバープッシュと優先度の関係も話しました。サーバープッシュを使用した場合、プッシュを発動したストリームにプッシュストリームが依存することが (危うく見逃すほど簡単に) 仕様書に書かれています。HTTP/2 における優先度はクライアント側が指定するものであり、サーバーが開始するサーバープッシュの優先度にはデフォルトの重み (16) が割り当てられることや、クライアントに到達してから必要に応じて変更されることも理解しておく必要があります。
このような仕組みにより、サーバープッシュの使い方によっては、優先度ツリーをブラウザが予期していない状態に変更してしまう可能性があり、それによりリソースの読み込み遅延を引き起こす可能性があると言えます。もしサーバープッシュを本格的に多用する場合は、一般的なパフォーマンス改善手法と同様に、きちんとした計測と検証が必要になるのではと考えています。
では「どうやって計測すればいいの?」ということになるのですが、現状ではよいツールは存在しません。Chrome の DevTools は非常に優秀ですが、HTTP/2 の優先度情報は表示されませんし、サーバーからどのストリームのデータがどのタイミングで送られてきたかを知る手段はありません。実は今回の発表にあたって、Wireshark と組み合わせて簡単に可視化できるツールを作ろうと考えましたが、Wireshark が正しく HTTP/2 のフレームを判定してくれないパターンが存在したため、やむなく断念しました。今回の話で検証に使用したサーバーが、フレーム情報をダンプできる nghttp2 だけだったのは、これが理由です。
今回の話で優先度についての理解がだいぶ深まったので、今後はそろそろ実際のサイトに HTTP/2 を適用してみつつ、色々とデータをとってパフォーマンス等の影響を検証してみたいと考えています。その際はやっぱり可視化ツールも必要になると思うので、また良い方法を考えてみないとですね。