Cloudfront HTTP/3対応はどの程度の効果があるのか?
注意事項
本記事は自分の研究用の記録をメインの目的として残しています。
中には仕様が定かではないソースや自分の勉強不足からくる誤解が書いてある可能性があります。あらかじめご了承ください。
Introduction
こんにちは。最近研究の記録で残していたQUIC関連の記事が技術書店でQUIC周りの本を出している方にいいねもらったりtwitterで共有していただいて嬉しい反面緊張しているゆーじんです。
今回はcloudfrontでHTTP/3で通信できるようになったということで(去年の話ですが)、どれだけ効果があるのか見てみようと思います。紹介では以下のように謳ってます。
CloudFront の利用者が配信で HTTP/3 を有効にした場合、最初の 1 バイトを受信するまでの時間が最大 10% 改善され、ページのロード時間が最大 15% 改善されました。
ついでにパケットキャプチャをしてQUICのハンドシェイクの流れを観察してみます。
Cloudfront HTTP/3 実験
実験環境
AWS上に同じ環境を二つ作って実験することにしました。コンテンツは同じものを置いています
(自分のHPと同じものです)
AWS Cloudfront
- ENV-1 HTTP/3,1.1対応
- ENV-2 HTTP/2,1.1 対応
キャッシュポリシー等、他の設定はすべて同一、HTTP/1.1はデフォルトで有効になっており、無効化はできませんでした
S3
- S3暗号化のみ実施(SSE-S3)
- 静的ウェブサイトホスティング機能を利用してコンテンツをホスト
構成図としてはこんな感じですね。ベーシックな感じです。
検証手段
計測に関しては完全素人なので、どんな方法があるのか調べてみました。
代表的な計測方法
- Google Pagespeed Insight(機能せず)
- Test My site(サービス終了)
- Chrome Developer Tool
今回は三つ目のDeveloper Toolで計測していく
検証にあたり以下を実施しました
- ブラウザ側のキャッシングの設定は無効に
- HTTP/2の方を検証するとき、フォント情報やbootstrapのjavascript等は外部サイトからHTTP/3でDLして来ているため、ブラウザでHTTP/3を無効にする
ネットワーク環境は以下の通りです
有線LAN 上り: 900Mbps 下り: 1.1Gbps (by fast.com)
有効化されているかをみてみる
h2と書かれているのがHTTP/2、h3と書かれているのがHTTP/3です。しっかりブラウザは使い分けて通信してくれているようですね
ページ読み込み完了までの速度を計測してみる
50回計測してページ読み込み完了までの速度を見てみました
結果平均でHTTP/3は99.1 ms、 HTTP/2は99.26 ms とあまり速度に差は出ませんでした。
阿部寛の時に約70msだったのでなんか負けた気になります(コンテンツの大きさが全然違うので負けるのは仕方ないですが...)
ちなみに阿部寛は5 requests 38kb,自分は15requests 1.9MBでした。
HTMLのDLまでで計測してみる
ブラウザは最初にHTMLファイルを読み込み、その後CSS,JSと続きます
CSS/JSは外部サイトを使っているため、documentまでの読み込み時間を計測することで差が出るかみてみます。
結果平均でHTTP/3は6.08 ms、HTTP/2 4.88とHTTP/3の方が劣っていることが分かった(全体的に負けてますね)
大きいコンテンツのDLを試してみる
大きいファイルをやり取りする場合はどのように変わるか?というのを試してみます
サイトに4Kや8Kの画像を合計6枚ほど貼り付けて再度全体の読み込みが終わるまでの時間をみてみます
また別の場所で検証したのでネットワーク環境は以下のようになっています。
有線LAN 上り:420Mbps、下り:350Mbps
コンテンツの量は21.7MBで、前回の1.9MBよりは遥かに多くなってますね
先ほどのものとはネットワーク自体が強くないので値の大きさについてはご留意ください。
HTTP/3だと889.98ms、HTTP/2だと472.76msでした
...負けてますね.....
考察
考察を書き残しておきます。
ユーザ空間・カーネル空間問題
- QUICは基本的にChrome内で定義され、実行される
- TCPはOSのカーネルで実行される
一般的には後者のほうが実行速度は早いとされる
これのせいでQUICの方が時間がかかってしまった説
図にしてみるとこんな感じですかね
Dissecting Performance of Production QUICより
全体的なパフォーマンスの左右要因は
- サーバーの輻輳制御アルゴリズムの選択
- エッジケースのネットワークシナリオにおける輻輳制御の実装の堅牢性
クライアントの中は、最適なパフォーマンスを得るために、自明ではない設定の調整が必要
- サーバーが想定している暗号スイートと違うものを使用していると遅延が起きる
ウェブページのパフォーマンスには、HoLの削除の影響は小さい
など、色々な要因もあるようです。
この方の記事がとてもわかりやすいです
ChromeがHTTP/3を使うまでの流れに問題が?
HTTP/3を使うまでの流れは以下のようになっているようです
- 一旦サーバとTCPでハンドシェイクをする(サーバがHTTP/3対応しているか調べるため)
- HTTPリクエストを受け取ったらサーバはレスポンスにAlt-Svc: h3属性を入れて返答する(QUICのバージョンネゴシエーションの代替)
- クライアントはQUICのコネクションを張りなおす
HTTP/2を使うのであればTLSのハンドシェイクの時にネゴシエートされるのですが、今回はそうはいきません。そのためワンクッション置く形で上記が行われています。
仕方ないとは言え、これは少し無駄なアクションにも見えますね。
まとめ
サイトが簡単にHTTP/3対応できるといっても、今回のように遅くなったりしてしまうようです。
プロダクションのようなサイトに適用するのは簡単ですが、何も考えず有効化するよりホストしているサイトが対応することで、UXにどのようなメリット・デメリットがあるか吟味した上で行う方がいいのかもしれません。
また、これからHTTP/3がスタンダードになってくるとこういった力関係も変わっていくのかもしれません。まだまだ目が離せませんね、では!
p.s. こうしたらHTTP/3のほうが早くなるよ!という知見をお持ちの方、ぜひ教えてください。
おまけ QUICのハンドシェイクを観察してみる
今回の記事で取り上げたCloudfrontとの通信で行われたQUICのハンドシェイクを見てみます
全体図は以下の画像の通りです
クライアントからサーバへのinitalパケット
先ほどの赤い枠の部分です。
サーバにinitialパケットの中にCRYPTOフレームなどいろんな情報を埋め込んでcloudfrontの方に投げています。
サーバからクライアントへのhandshakeパケット
オレンジ枠の部分です。
先ほどの画像ではhandshakeしかないと思いますが、サーバはinitialパケットも返しますよね。
ということでオレンジ枠一個目の部分をクリックしてみます。
ここにはinitlalパケットがありますね。(ピンク)
パケットが連結してるように見えますがこれはストリームの影響なんですかね?
その他のパケットは茶色枠と同じようにhandshakeとして送られてきます。
ハンドシェイク図における以下の部分がここで完了しました。
クライアントからサーバへのhandshakeパケットとデータ送信
灰色の部分です。濃い灰色の枠はハンドシェイクが完了したということでクライアントからサーバに対してhandshakeが送られます
その後続いてデータが送信されます(黒枠)
ハンドシェイク図における以下の部分がここで完了しました。
その後は緑枠の部分のようにデータの通信が続きます。QUICパケットとはわかるもののパケットが暗号化されているのでProtected Payloadと出るんですね。
いつの間にWiresharkでもQUICパケットがしっかりQUICと出るようになったんですね(前はUDPだった記憶)
Discussion