Skip to content
⚠️ This article was written in 2018. Some content may be outdated.

HTTP/2 がフロントエンドリソース読み込みに与える実際の影響

HTTP/2 は数年前から存在していますが、多くのフロントエンド開発者は、実際に何が変わったのか、フロントエンド最適化戦略にどのような影響を与えるのかをまだよく理解していません。この記事では実際の変化について説明します。

HTTP/1.1 の主なボトルネック

HTTP/1.1 の時代、ブラウザは同一ドメインへの同時リクエスト数を制限していました(通常 6 つ)。これが古典的な問題を引き起こしました:

リソース 1 ──── 待機 ──────── 読み込み
リソース 2 ──── 待機 ──────────── 読み込み
リソース 3 ──── 待機 ────────────── 読み込み
リソース 4                 ─── 待機 ──── 読み込み
リソース 5                 ─── 待機 ──────── 読み込み
リソース 6                 ─── 待機 ────────── 読み込み

この制限を回避するために、多くの「テクニック」が生まれました:

  • ドメインシャーディング:リソースを複数のサブドメインに分散
  • CSS スプライト:複数の小さな画像を1枚の大きな画像にまとめる
  • ファイル結合:複数の JS/CSS ファイルを1つの大きなファイルにまとめる

HTTP/2 の多重化

HTTP/2 の核心的な改善は**多重化(Multiplexing)**です:1つの TCP 接続で複数のリクエストとレスポンスを同時に転送でき、同時数の制限がなくなりました。

HTTP/1.1                    HTTP/2

リクエスト1  ─── レスポンス1      リクエスト1 ─┐ レスポンス1 ─┐
待機...                          リクエスト2  ├──────        ├── 同時
リクエスト2  ─── レスポンス2      リクエスト3  ┘ レスポンス2  │
待機...                                        レスポンス3 ─┘
リクエスト3  ─── レスポンス3

フロントエンド最適化戦略への影響

ドメインシャーディングはもう不要

HTTP/1.1 の時代は cdn1.example.comcdn2.example.com で同時接続数制限を回避していましたが、今ではむしろ有害です:

  • HTTP/2 の多重化は同一接続上で動作する
  • 複数ドメイン = 複数の TCP 接続 = より多くのハンドシェイクオーバーヘッド
  • 結論:HTTP/2 では同一ドメインに統合する方が良い

ファイル結合戦略が変わった

HTTP/1.1:すべての JS を1つの大きなファイルにまとめてリクエスト数を減らす HTTP/2:リクエスト数はボトルネックではなく、細かくファイルを分割できる

javascript
// HTTP/1.1 時代の Webpack 設定思想:できるだけ結合してファイル数を減らす

// HTTP/2 時代:モジュールごとに分割してブラウザキャッシュを細かく活用
optimization: {
  splitChunks: {
    cacheGroups: {
      vue: { test: /vue/, name: 'vue', chunks: 'all' },
      axios: { test: /axios/, name: 'axios', chunks: 'all' },
      elementUI: { test: /element-ui/, name: 'element-ui', chunks: 'all' }
    }
  }
}

細粒度分割のメリット:vue のバージョンが変わらない場合、ユーザーは新バージョンにアクセスしても vue.js を再ダウンロードする必要がありません。

サーバープッシュ

HTTP/2 はサーバーが積極的にリソースをプッシュすることをサポートしています:

ブラウザ: index.html をリクエスト
サーバー: index.html をどうぞ、main.css と main.js も送ります(どうせ必要になるので)
ブラウザ: (main.css と main.js はすでにローカルにある、追加リクエスト不要)

Nginx のサーバープッシュ設定:

nginx
location = /index.html {
  http2_push /static/main.css;
  http2_push /static/main.js;
}

CSS スプライトはまだ価値がある(一部のシナリオ)

HTTP/2 が同時リクエストの問題を解決しても、小さなアイコンをすべて個別ファイルにするとオーバーヘッドが残ります。アイコンフォントや SVG スプライトは依然として優れたアイコンソリューションです — リクエスト数のためではなく、制御性と保守性のためです。

サイトが HTTP/2 を使っているか確認する

Chrome DevTools の Network パネルでヘッダー行を右クリックして「Protocol」列を有効にします:

  • h2 = HTTP/2
  • http/1.1 = HTTP/1.1

サーバーがまだ HTTP/2 にアップグレードしていない場合の Nginx 設定:

nginx
server {
  listen 443 ssl http2;          # ポイント:http2 を追加
  ssl_certificate /path/to/cert.pem;
  ssl_certificate_key /path/to/key.pem;

  # HTTP/2 は HTTPS が必要なので、まず HTTPS を正しく設定すること
}

実際のベンチマークデータ(参考)

管理画面プロジェクト(約 30 個の JS/CSS ファイル)での比較:

シナリオ初回読み込み時間
HTTP/1.12.8秒
HTTP/21.6秒
HTTP/2 + サーバープッシュ1.2秒

ネットワーク環境によって差はありますが、HTTP/2 の改善は通常明確です。

まとめ

  • HTTP/2 の多重化は同時数制限を解決し、HTTP/1.1 時代の多くの「最適化テクニック」は不要になった
  • ドメインシャーディングはむしろ有害で、同一ドメインに統合する方が良い
  • ファイルを細かく分割してキャッシュ利用率を向上できる
  • サーバープッシュは追加の恩恵だが、サーバー側のサポートが必要
  • HTTP/2 にアップグレードするには HTTPS が先に必要

MIT Licensed