仕組みから学ぶ Web
応用読了目安 14#HTTP#HTTP/2#QUIC#多重化

HTTP/1.1 → 2 → 3 — 何が遅くて、何を直したのか

バージョンが上がるたびに解かれてきたのは「待ち」の問題。どの待ちがどこで消えたかを知らないと、HTTP/2 にしても速くならない。

先に読んでおくとよい記事

この記事の進み方

What — 3世代で何が変わったか

まず、それぞれが何を解いたのかを切り替えて見比べてください。

Compare1リクエストが待たされる原因は、世代ごとに別の場所へ移った

1本の接続で1件ずつ。前のレスポンスが返るまで、次は送れない。

接続1: [req A][... A待ち ...][res A][req B][... B待ち ...][res B]

ブラウザは同一ホストに 6 本まで接続を張ることで
無理やり並列化していた(= ドメイン分割が有効だった時代)
同時リクエスト
接続1本につき1件
ホストあたり接続数
6本前後(ブラウザ制限)
ヘッダ
毎回すべて平文で送る
HOL ブロッキング
HTTP レベルで発生
接続確立
  • Cookie が 2KB あれば、100 リクエストで 200KB をヘッダだけで送ることになる。
  • この制約を回避するための技法が、ドメイン分割・CSS スプライト・ファイル結合だった。

どの世代も「待ち」を潰してきたが、潰しきれなかった待ちが次の世代の課題になっている。自分のサイトがどの待ちで損しているかを知らないまま上げても、体感は変わらない。

HOL ブロッキングが「どの層で起きるか」を追う

HTTP/2 の説明でいちばん誤解されるのが、ここです。HTTP/2 は HOL ブロッキングを解決していません。発生する層を1つ下げただけです。

FigureHTTP/2 でパケットが1つ欠けたとき何が起きるか
ブラウザHTTP/2TCP受信バッファサーバーA・B・C を同時に要求A の一部(パケット1)A の一部(パケット2)が消失B・C のデータ(到着済み)順番待ちで保留パケット2 を再送A・B・C をまとめて渡す
1/7
A・B・C を同時に要求3つのストリームを1本の接続に流す。ここまでは HTTP/2 の狙いどおり。

HTTP のレベルでは A・B・C は独立している。しかし全部が同じ TCP 接続に乗っているため、TCP から見れば1本のバイト列でしかない。欠けた部分より後ろは、揃っていても渡されない。

HTTP/3 がわざわざ TCP を捨てて UDP に移ったのは、この「TCP の順番保証の粒度が粗すぎる」問題を、TCP の中では直せなかったからです。

確認 — ここまで読めたか

HTTP/2 で解消された HOL ブロッキングは、どの層のものですか?

まず選ぶ(解答例は a〜d の記号で説明します)

Why — なぜ3回も作り直したのか

HTTP/1.1 の設計は、当時としては正しかった

HTTP/1.1 が固まった1997年、Web ページは HTML 1枚と画像が数枚でした。1リクエストずつ順番に処理する設計で困りません。むしろ実装が単純で、どんな貧弱なサーバーでも動くことが価値でした。

問題が出たのは、ページあたりのリクエスト数が10件から100件へ増えてからです。設計が間違っていたのではなく、前提が変わったのです。

現場は回避策を積み上げた

仕様が変わらないので、現場は HTTP/1.1 の制約を回避する技法を発明しました。

  • ドメイン分割 — ブラウザの「同一ホスト6接続まで」を、ホストを増やして突破する
  • CSS スプライト — 小さい画像を1枚に結合し、リクエスト数を減らす
  • ファイル結合・インライン化 — CSS や JS を1つにまとめる

どれも「リクエスト数が多いと遅い」という制約への対処です。ここが重要で、HTTP/2 でその制約が消えると、これらはコストだけが残ります。スプライト画像は、1枚しか使わないページでも全体をダウンロードさせますし、ドメイン分割は接続を分断します。冒頭の事故はこれでした。

なぜ HTTP/2 で TCP を捨てられなかったのか

HTTP/2 の設計時も、TCP の HOL ブロッキングは認識されていました。それでも TCP を使い続けたのは、世界中の中間機器が TCP しか通さなかったからです。企業のファイアウォール、NAT、プロキシの多くは、UDP を通さないか、通しても特別扱いします。

HTTP/3 が現実的になったのは、QUIC が UDP の上で動き、暗号化によって中間機器から中身が見えなくなり、かつ「通らなければ HTTP/2 に自動で戻る」というフォールバックを持てるようになってからです。技術的な正しさだけでは普及せず、既存の設備との折り合いが必要だったという話でもあります。

確認 — ここまで読めたか

HTTP/1.1 向けにドメインを4つに分けていた構成を、HTTP/2 でそのままにするとどうなりますか?

まず選ぶ(解答例は a〜d の記号で説明します)

演習 — まず自分で判断する

解説を読む前に、まず自分で判断してみてください。ここで一度詰まっておくと、 次の節の判断軸が「なるほど」ではなく「そう来たか」に変わります。

演習 — 設計判断を問う

この構成で HTTP/2 に移行するとき、何から手を付けますか?

与えられた条件
  • EC サイトの商品一覧ページ。1ページあたり約 120 リクエスト(画像100・CSS 5・JS 12・API 3)
  • 画像は img1〜img4.example.com の4ドメインに分散配信している
  • CSS と JS はそれぞれ1ファイルに結合済み(CSS 340KB / JS 890KB)
  • アイコン類は 180KB の CSS スプライト1枚にまとめている
  • 利用者の 7 割がスマートフォン
  • CDN の設定変更だけで HTTP/2 も HTTP/3 も有効化できる
この軸で考える
  • · どの最適化が HTTP/1.1 の制約への回避策で、今は不要になるか
  • · リクエスト数が減ることと、転送量が減ることのどちらが効くか
  • · 利用者の回線品質が効いてくるのはどの選択肢か
まず選ぶ(解答例は a〜d の記号で説明します)

演習 — 説明できるか

「HTTP/2 にしたのに速くならない」と言う同僚に、何を確認すべきかを説明してください

与えられた条件
  • 相手は CDN の設定で HTTP/2 を有効にしただけ
  • サイトには画像用の別ドメインが4つある
  • CSS スプライトで画像を結合している

読み終わりましたか?

読了にすると、これを前提とする記事がロードマップで開放されます。

この記事を前提にしている記事