high-perf-browser について
ブラウザー、プロトコル、ネットワークの仕組みに基づいてWebパフォーマンスを改善するフレームワークです。読み込み速度、サーバー設定、パフォーマンス予算、問題診断に取り組むフロントエンド開発者や運用担当者を対象とします。
主な機能
- 01ネットワーク遅延とハンドシェイクの分析
- 02HTTP/1.1、HTTP/2、HTTP/3の指針
- 03重要リソースの読み込み戦略
- 04ブラウザー、Service Worker、CDNのキャッシュ
- 05Core Web Vitalsの最適化
- 06WebSocket、SSE、ポーリングの指針
活用シーン
- 01ページ表示の遅さや通信確立の診断
- 02プロトコル選定とリソース配信の設定
- 03静的アセットやAPIのキャッシュ方針策定
- 04実ユーザーデータを基にしたLCP、INP、CLSの改善
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ wondelai/ skills --skill high-perf-browserインストール後、Claude Code で/high-perf-browserを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/caching-strategies.mdcore-web-vitals.mdhttp-protocols.mdnetwork-fundamentals.mdreal-time-communication.mdresource-loading.md詳細
高パフォーマンスブラウザーネットワーキングフレームワーク
ブラウザー、プロトコル、ネットワークの実際の仕組みに基づく、ウェブパフォーマンスへの体系的なアプローチです。フロントエンドアプリケーションの構築、パフォーマンス予算の設定、サーバーの構成、ページ読み込みの遅さの診断に、これらの原則を適用してください。
基本原則
ボトルネックは帯域幅ではなく、レイテンシです。 ウェブパフォーマンスの問題の多くは、スループット不足ではなく、ラウンドトリップの多さに起因します。帯域幅を5倍にしても効果は次第に小さくなりますが、レイテンシを5分の1にすれば、ユーザー体験は大きく変わります。
基盤: コンテンツの1バイト目が届くまでに、すべてのリクエストでDNS解決、TCPハンドシェイク、TLSネゴシエーション、HTTP通信が行われます。それぞれのステップでラウンドトリップレイテンシが加わります。高パフォーマンスなアプリケーションは、ラウンドトリップを最小限に抑え、リクエストを並列化し、不要なネットワークホップをなくします。意味のある最適化を行うには、プロトコルスタックを理解することが前提です。
スコアリング
目標:10/10。 8つの「クイック診断」の行のうち、合格した行数に基づいてスコアを算出します。フィールドメトリクスを重視します。9-10 = 8行すべてに合格(緑のフィールドメトリクス4行に加え、コンテンツハッシュ、HTTP/2以上、レンダリングをブロックする要素の最小化、圧縮にも合格);5-6 = フィールドメトリクス4行には合格しているものの、トランスポート、キャッシュ、圧縮に関する行のうち1行以上に不合格;<=3 = フィールドメトリクスの行が1行でも赤。必ずスコア、不合格となった診断項目、各項目に対する具体的な修正方法を報告してください。
高パフォーマンスブラウザーネットワーキングフレームワーク
高速でレジリエントなウェブアプリケーションを構築するための6つの領域:
1. ネットワークの基礎
基本概念: すべてのHTTPリクエストでは、アプリケーションデータの送信が始まる前に、DNSルックアップ、TCPの3ウェイハンドシェイク、TLSネゴシエーションによるレイテンシコストが発生します。こうしたラウンドトリップを減らす、あるいはなくすことが、最も効果の高い最適化です。
効果がある理由: 光は有限の速度で伝わります。ニューヨークからロンドンまでのパケットは、帯域幅に関係なく、片道で約28msかかります。こうした物理的制約は、より太い回線では解消できず、通信回数を減らすことでしか解消できません。
重要なポイント:
- TCPの3ウェイハンドシェイクによって、データ転送の開始前に1 RTTが丸ごと加わります
- TCPのスロースタートにより、最初のラウンドトリップにおける初期スループットは約14KB(10セグメント)に制限されます。重要なリソースはこのしきい値以下に抑えてください
- TLS 1.3にアップグレードしましょう。TLS 1.2と比べてハンドシェイクのラウンドトリップが半分になり、再訪問者向けの0-RTT再開が可能になります
- TCPのヘッドオブラインブロッキングにより、パケットを1つ失うだけで、その接続上のすべてのストリームが停止します
- 帯域幅遅延積によって転送中のデータ量が制限されるため、レイテンシの高いリンクでは帯域幅を十分に活用できません
コードへの適用例:
| コンテキスト | パターン | 例 |
|---|---|---|
| 接続のウォームアップ | 重要なオリジンへの接続を事前に確立する | <link rel="preconnect" href="https://cdn.example.com"> |
| DNSプリフェッチ | サードパーティのドメインを早めに解決する(20~120ms短縮) | <link rel="dns-prefetch" href="https://analytics.example.com"> |
| TLSの最適化 | TLS 1.3 + セッション再開 | セッションチケットを使ったssl_protocols TLSv1.3; |
| 接続の再利用 | Keep-Aliveによりハンドシェイクの繰り返しを回避する | Connection: keep-alive(HTTP/1.1以降のデフォルト) |
サーバーのチューニングやハンドシェイクレイテンシの診断については、references/network-fundamentals.mdを参照してください。TLS 1.2と1.3のRTT導出の詳細、スロースタートの倍増表、initcwnd/BDPの計算、OCSPステープリングのNginx設定、DNSキャッシュ階層が記載されています。
2. HTTP プロトコルの進化
中心となる概念: HTTP は、シンプルなリクエスト・レスポンス型のプロトコルから、多重化されたバイナリシステムへと進化しました。適切なプロトコルバージョンを選び、正しく設定することで、パフォーマンス問題のカテゴリ全体を解消できます。
効果がある理由: HTTP/1.1 では多重化できないため、ドメインシャーディング、スプライト、連結などの回避策が必要です。HTTP/2 は多重化できますが、TCP のヘッドオブラインブロッキングを引き継ぎます。HTTP/3(UDP 上の QUIC)はこれを解消します。世代が進むごとにボトルネックが取り除かれ、以前の世代で使われていた回避策は逆効果になります。
主なポイント:
- HTTP/1.1 では、TCP 接続ごとに未完了のリクエストを 1 つしか処理できません。回避策として、ブラウザーはホストごとに 6 つの接続を開きます
- HTTP/2 は 1 つの接続で無制限のストリームを多重化するため、ドメインシャーディングは逆効果になります
- HTTP/2 の HPACK ヘッダー圧縮により、繰り返し発生するヘッダーのオーバーヘッドを 85~95%削減できます
- HTTP/3(QUIC)は TCP のヘッドオブラインブロッキングを解消し、0-RTT 再開と接続の移行を可能にします
- HTTP/2 Server Push は過剰にプッシュし、広く非推奨となっているため、代わりに
103 Early Hintsを優先してください - 接続のコアレッシングにより、証明書を共有する複数のホスト名に 1 つの HTTP/2 接続を使用できます
コードでの適用例:
| コンテキスト | パターン | 例 |
|---|---|---|
| HTTP/2 への移行 | HTTP/1.1 の回避策を削除する | ドメインシャーディング、スプライト、ファイル連結を元に戻す |
| 103 Early Hints | 完全なレスポンスの前にプリロードのヒントを送信する | Link: </style.css>; rel=preload を含む 103 |
| QUIC/HTTP/3 | CDN またはオリジンで HTTP/3 を通知する | Alt-Svc: h3=":443" ヘッダー |
| ストリームの優先順位付け | リソースの重要度を示す | CSS とフォントを最優先にし、画像は低優先度にする |
プロトコルバージョンの選択や移行については、references/http-protocols.md を参照してください。HTTP/1.1・2・3 の比較、段階的なシャーディング解除の手順、Server Push が 103 Early Hints に取って代わられた理由を説明しています。
3. リソース読み込みとクリティカルレンダリングパス
中心となる概念: ブラウザーはピクセルを描画する前に DOM、CSSOM、レンダーツリーを構築する必要があります。HTML → DOM → CSSOM → レンダーツリー → レイアウト → ペイント → 合成の順に処理されます。この処理をブロックするリソースは、すべて最初のペイントを遅らせます。
効果がある理由: CSS はレンダリングをブロックし(CSSOM の準備が完了するまで描画されません)、JavaScript はパーサーをブロックします(<script> に達すると、ダウンロードと実行が完了するまで DOM の構築が停止します)。そのため、それぞれに異なる最適化戦略が必要です。ブロックするリソースは、どれも初回ペイントまでの時間に直接遅延を加えます。
主なポイント:
asyncは並列でダウンロードし、すぐに実行します(独立したスクリプトに使用)。deferは並列でダウンロードしますが、DOM の解析後に実行します(ほとんどのスクリプトに使用)<link rel="preload">は重要なリソースを今すぐ高い優先度で取得します。rel="prefetch"は次のナビゲーションで使われそうなリソースを低い優先度で取得します- ファーストビューの CSS をインライン化し、残りを非同期で読み込むことで、レンダリングをブロックする CSS リクエストをなくします
- フォントは最大 3 秒間テキストの描画をブロックする場合があります。
font-display: swapを使用してください
コードでの適用例:
| コンテキスト | パターン | 例 |
|---|---|---|
| クリティカル CSS | <head> にファーストビューのスタイルをインライン化する | <style>/* critical */</style> + CSS 全体を非同期で読み込む |
| スクリプトの読み込み | デフォルトでは defer、独立したスクリプトには async | <script src="app.js" defer></script> |
| リソースヒント | 重要なフォントやメイン画像をプリロードする | <link rel="preload" href="font.woff2" as="font" crossorigin> |
| 画像の最適化 | ファーストビューより下は遅延読み込みし、最新の形式を使用する | <img loading="lazy" src="photo.avif" srcset="..."> |
初回ペイントを短縮する際は、references/resource-loading.md を参照してください。async/defer/module の正確な実行順序、リソースヒントの完全な判断フロー、画像とフォント(font-display、srcset、AVIF)の実践ガイドを説明しています。
4. キャッシュ戦略
基本概念: 最速のネットワークリクエストは、発生しないリクエストです。ブラウザーのメモリー、ディスク、サービスワーカー、CDN、オリジンにキャッシュを重ね、再訪問者のラウンドトリップをなくします。
効果がある理由: Cache-Control ヘッダーは、レスポンスが有効な期間をブラウザーや中間サーバーに正確に伝えます。コンテンツハッシュ付き URL を使えば、積極的な不変キャッシュも安全に行えます。キャッシュがヒットするたびに、ネットワークのラウンドトリップ全体を省略できます。
主なポイント:
Cache-Control: no-cacheはキャッシュを保存しますが、毎回再検証します。no-storeはキャッシュを保存しません。混同しないでください。ETag/Last-Modifiedを使うと、条件付きリクエスト(304 Not Modified)が可能になり、本文の転送を省略できます。- サービスワーカーは、オフラインでも動作するプログラム可能なキャッシュ層を提供します(シェルはキャッシュ優先、動的コンテンツはネットワーク優先)。
Varyヘッダーの設定を誤ると CDN のキャッシュが汚染され、誤ったエンコーディングや形式がクライアントに配信されます。
コードでの適用例:
| コンテキスト | パターン | 例 |
|---|---|---|
| 静的アセット | 不変キャッシュ+ハッシュによるキャッシュ無効化 | style.a1b2c3.css に Cache-Control: max-age=31536000, immutable を設定 |
| HTML ドキュメント | リクエストごとに再検証 | ETag を指定した Cache-Control: no-cache |
| API レスポンス | 短い TTL+バックグラウンドでの更新 | Cache-Control: max-age=60, stale-while-revalidate=3600 |
| CDN の設定 | 適切な Vary を指定してエッジでキャッシュ | Vary: Accept-Encoding, Accept |
キャッシュポリシーを設計する際は、references/caching-strategies.md を参照してください。ブラウザー/SW/CDN/オリジンの階層全体、コピーして使えるサービスワーカーのキャッシュ優先とネットワーク優先のレシピ、CDN を汚染する Vary の落とし穴について説明しています。
5. Core Web Vitals の最適化
基本概念: Core Web Vitals(LCP、INP、CLS)は、読み込み、インタラクティブ性、視覚的安定性を対象とした、Google のユーザー中心の指標です。検索順位に影響し、実際のユーザー体験を反映します。
効果がある理由: TTFB が速くても、メインの画像の読み込みが遅れたり(LCP)、メインスレッドの JavaScript が操作を妨げたり(INP)すれば意味がありません。そのため、サーバー側の計測値が良好でも、ユーザーは待たされることがあります。バイトの配信時間ではなく、ユーザーが体感する各段階を最適化してください。
主なポイント(数値による合格/不合格のしきい値は「Quick Diagnostic」に記載):
- LCP — 最も大きく表示される要素(メイン画像、見出しブロック、動画のポスター画像)を最適化します。
- INP — メインスレッドを空けておき、長いタスクを分割して、すべての操作(最初の操作だけでなく)が応答性を保つようにします。
- CLS — 動的コンテンツが読み込まれる前に、その表示領域を確保します。
- TTFB と FCP(< 1.8s)は上流のゲートです。後続の各段階の上限を決めるため、まずこれらを改善してください。
- 本番環境でリアルユーザーモニタリング(RUM)を使って測定します。ラボテストや合成テストでは、実際のデバイスやネットワークのばらつきを把握できません。
コードでの適用例:
| コンテキスト | パターン | 例 |
|---|---|---|
| LCP | LCP 要素をプリロードし、優先度を上げる | <img src="hero.webp" fetchpriority="high"> |
| INP | 長いタスクを分割し、メインスレッドに制御を返す | scheduler.yield() または setTimeout による分割 |
| CLS | 非同期コンテンツの表示領域を確保 | <img width="800" height="600"> または CSS の aspect-ratio |
| パフォーマンスバジェット | 指標が「Quick Diagnostic」のしきい値を超えて悪化した場合に CI を失敗させる | LCP/INP/CLS に対する Lighthouse CI のアサーション |
指標が基準を下回っている場合は、references/core-web-vitals.md を参照してください。指標ごとのデバッグ手順(LCP/INP/CLS の値が悪い場合に確認すること)、ラボテストと RUM のツール対応表、各指標の最適化チェックリストについて説明しています。
6. リアルタイム通信
中心となる概念: データを継続的に流す必要がある場合、トランスポートの選択(WebSocket、SSE、ロングポーリング)によって、レイテンシ、リソース使用量、スケーラビリティが決まります。
効果がある理由: HTTP のリクエスト/レスポンスモデルでは、リアルタイム更新のたびにオーバーヘッドが発生します。WebSocket は約 2 バイトのフレーミングで全二重通信を実現します。SSE は通常の HTTP 上で、よりシンプルなサーバーからクライアントへのプッシュを実現します。最も高機能な選択肢を最初から採用するのではなく、データの流れる方向と頻度に合わせてトランスポートを選びます。
重要なポイント:
- WebSocket:双方向(チャット、ゲーム、共同編集)。SSE:サーバーからクライアントへの一方向のみ、自動再接続、プロキシとの親和性が高く、よりシンプル
- ロングポーリングは代替手段に限ります。HTTP リクエストを繰り返すため、オーバーヘッドが大きくなります
- WebSocket はそれぞれ独立した TCP 接続を使用するため、HTTP/2 の多重化を迂回します
- ハートビート/ping フレームを送信します。モバイルネットワークでは、アイドル状態の接続が通知なく切断されます
- 指数バックオフで再接続し、切断中はメッセージをキューに入れます
コードでの適用例:
| コンテキスト | パターン | 例 |
|---|---|---|
| チャット/共同作業 | WebSocket + ハートビート + 再接続 | new WebSocket('wss://...') を使い、30 秒ごとに ping を送信 |
| ライブフィード/通知 | サーバーからクライアントへのストリーミングに SSE を使用 | new EventSource('/api/updates') |
| 接続の耐障害性 | 再接続時に指数バックオフ | 1 秒、2 秒、4 秒、8 秒……最大 30 秒 |
| スケーリング | WebSocket サーバーの背後に Pub/Sub ブローカーを配置 | Redis Pub/Sub または NATS |
ライブ機能を構築する際は、references/real-time-communication.md を参照してください。WebSocket の接続/ハートビート/再接続のライフサイクル、SSE の EventSource パターン、Pub/Sub ブローカーの背後でファンアウトをスケールする方法について説明しています。
よくある間違い
| 間違い | 失敗する理由 | 修正方法 |
|---|---|---|
| ページの読み込みが遅い問題を帯域幅の増強で解決する | ボトルネックはスループットではなくレイテンシです | ラウンドトリップを削減します。事前接続、キャッシュ、CDN を活用します |
| JavaScript をすべて最初に読み込む | パーサーをブロックするスクリプトが描画と操作性を遅らせます | コードを分割します。defer を使用します。重要でないモジュールは遅延読み込みします |
| リソースヒントを設定しない | ブラウザーが重要なリソースを発見するのが遅すぎます | 画面上部に表示される重要なリソースに preconnect と preload を使用します |
Cache-Control の設定がない、またはすべてに no-store を設定する | アクセスするたびにすべてを再ダウンロードします | 適切な max-age とコンテンツハッシュを設定します |
| CLS を無視する | レイアウトのずれによって信頼とランキングが損なわれます | 画像、埋め込みコンテンツ、広告に明示的なサイズを指定します |
| 何にでも WebSocket を使う | SSE やポーリングで十分な場合にも、不要な複雑さが生じます | データフローに合わせてトランスポートを選びます。サーバープッシュには SSE を使用します |
| HTTP/2 でドメインシャーディングを行う | 多重化が無効になり、TCP 接続が余計に増えます | オリジンを統合し、HTTP/2 の多重化を活用します |
| 圧縮しない | テキストリソースが元のサイズのまま転送されます | サーバー/CDN で Brotli(推奨)または Gzip を有効にします |
クイック診断
| 質問 | いいえの場合 | 対処 |
|---|---|---|
| TTFB は 800ms 未満ですか? | サーバーまたはネットワークが遅すぎます | CDN、サーバーキャッシュを導入し、バックエンドを確認します |
| LCP は 2.5s 未満ですか? | 最大の要素の読み込みが遅すぎます | LCP リソースをプリロードします。fetchpriority="high" を設定します |
| INP は 200ms 未満ですか? | メインスレッドがブロックされています | 長時間タスクを分割し、重要でない JavaScript の実行を遅らせます |
| CLS は 0.1 未満ですか? | 描画後に要素がずれます | 明示的なサイズを指定し、スペースを確保します |
| 静的アセットにコンテンツハッシュが付与され、キャッシュされていますか? | 再訪問時にファイルが再ダウンロードされます | ハッシュ付きファイル名と Cache-Control: immutable を設定します |
| HTTP/2 または HTTP/3 が有効ですか? | 多重化もヘッダー圧縮も利用できません | サーバーで HTTP/2 を有効にし、CDN 経由で HTTP/3 を有効にします |
| レンダリングをブロックするリソースは最小限に抑えられていますか? | CSS と同期 JavaScript が初回描画を遅らせます | 重要な CSS をインライン化し、スクリプトに defer を指定し、未使用の CSS を削除します |
| 圧縮(Brotli/Gzip)は有効ですか? | 圧縮されていないテキストが転送されます | サーバー/CDN で Brotli を有効にし、フォールバックとして Gzip を使用します |
参考資料
Ilya Grigorik による、ブラウザーネットワーキングとウェブパフォーマンスに関する包括的なガイドをもとにしています。
- 「High Performance Browser Networking」 Ilya Grigorik 著(ネットワーキングプロトコル、ブラウザーの内部構造、パフォーマンス最適化に関する決定版の参考書です)
- hpbn.co -- 著者が管理する無料のオンライン版
著者について
Ilya Grigorik はウェブパフォーマンスエンジニアです。Google に10年以上在籍し、Chrome、ウェブプラットフォームのパフォーマンス、HTTP 標準に取り組み、W3C Web Performance Working Group の共同議長を務めました。著書 High Performance Browser Networking(O'Reilly、2013年)は、ブラウザーとネットワークの相互作用に関する決定版の参考書として広く知られています。