15kBのページより14kBのページのほうがはるかに速く読み込まれることがある(2022)
(endtimes.dev)- Webサイトのサイズを14kB以下に保つと、15kBの場合よりも読み込み速度を大幅に短縮できる
- この現象はTCPスロースタートアルゴリズムによって発生し、最初に送信できるデータ量の上限により体感速度の差が生じる
- 14kBは、ほとんどのサーバーが最初に送る10個のTCPパケットの容量に相当する
- 衛星インターネットなどの高レイテンシ環境では、1回の追加往復(RTT)が612ms以上の遅延を引き起こす
- 実際に14kB未満に主要コンテンツを収める、または最初の14kB以内に重要なリソースを配置することが、Webパフォーマンス最適化に有効である
概要と主要な原理
- Webサイトは小さいほど速く読み込まれることは広く知られている
- しかし、14kBから15kBに超えた瞬間に、最初の応答速度で劇的な差が生じるのは意外な事実である
- 15kBと16kBのページの速度差はわずかだが、14kBと15kBの間には最大612msの差が生じうる
TCPとは何か
- Transmission Control Protocol (TCP) は IP(Internet Protocol) の上で動作し、パケットの信頼性保証を担う
- WebブラウザーはHTTPリクエスト時に複数のTCPパケットを送信する
- IPだけを使う場合、パケットが到着したか確認できないため、TCPが**パケット受信確認(ACK)**機能を提供する
- サーバーはまず少量のパケットを送り、ブラウザーからACKを受け取ると追加のパケットを送信する
- ACKがない場合は、パケット再送の手続きが実行される
TCPスロースタートとは
- TCPスロースタートは、サーバーがネットワーク接続品質(帯域幅)を把握するために段階的にパケット送信量を増やしていくアルゴリズムである
- 接続初期にサーバーは少量(一般的には10個)のパケットだけを送信する
- 訪問者のコンピューターが正常にACKを返すと、パケット送信量を2倍に増やす
- ACKの欠落が発生すると、その後は遅い速度でパケットを送る
- 実際のアルゴリズムは実装ごとに細部の違いがあるが、概念は同じである
14kB基準の根拠
- ほとんどのサーバーはスロースタートでTCPパケット10個を一度に送る
- TCPパケットの最大サイズは1500バイトだが、ヘッダー(40バイト)を除くと1460バイトが実データとなる
- したがって 10 x 1460 = 14600バイト(約14kB) が最初の送信上限となる
- Webサイトまたは重要なリソースを14kB以下(圧縮適用時は元データで数十kB規模)に収めれば、開始時の往復遅延なしで表示できる
1回の往復がどれほど大きな遅延を引き起こすか
衛星インターネットの例
- 高レイテンシ環境の代表例として、衛星インターネット(石油掘削船、クルーズ船など)の利用者がいる
- 携帯電話からホームページをリクエストすると、ルーター → 衛星アンテナ → 宇宙衛星 → 地上局 → サーバーと移動し、各区間で数十〜数百msを要する
- 全体の伝送往復には、2回の宇宙往復、ネットワーク区間の移動、サーバー処理まで含めて約612msの追加遅延が発生する
- HTTPSを使う場合、追加のハンドシェイクにより1836msまで増えることがある
地上ネットワークのレイテンシ
- 2G、3Gなどのモバイルネットワークでも100〜1000msのレイテンシが発生する
- 混雑時やサーバー過負荷、パケット損失など、さまざまな環境で追加遅延が発生しうる
14kBルールを適用したWebサイト最適化戦略
- Webサイトやページをできるだけ小さくすることが重要である
- 各ページの圧縮後の転送量が14kB以下になるよう設計するのが理想的である
- 圧縮適用時には実コンテンツを約50kBまで含められる
- 自動再生動画、ポップアップ、トラッカー、不要なJS/CSSなど、ほとんどの不要要素を減らせば十分達成可能である
- もし14kBで全体を実装するのが難しいなら、最初の14kBに中核リソースと主要コンテンツ(CSS、JS、主要テキストなど)を優先配置することが重要である
- HTTPヘッダー(圧縮不可)、画像(必要最小限だけ/表示位置のみ読み込む、またはプレースホルダー適用)も14kB内に含まれる
14kBルールの例外と最新プロトコルの論点
- 14kBルールは極端な一般化ではないが、いくつかの例外がある
- 一部のサーバーは初期ウィンドウを30パケットに拡張している
- TLSハンドシェイクにより、より大きなウィンドウが許可される可能性がある
- ルートごとに送信可能なパケット数をキャッシュし、次回接続時により多く送れることがある
- HTTP/2でも、サーバーがTCPスロースタートで10パケットから始める慣行は概ね変わらない
- HTTP/3、QUICでも14kBルールは公式に推奨されている
要約と参考資料
- 技術的根拠と追加説明資料は各リンクから確認できる
- 初回公開: 2022-08-25、最終更新: 2022-08-26、著者: Nathaniel、関連タグ: Webパフォーマンス、HTTP、TCP
参考リンク
- EthernetフレームとTCPヘッダー構造、レイテンシおよび帯域幅に関する追加資料、TCP/QUIC仕様など
1件のコメント
Hacker Newsの意見
ソフトウェア開発者はメディア層にもう少し関心を持つべきだと思う。特に、3G/5Gの信頼性と遅延について著者が指摘している点が印象的だった。無線ではほぼ常に再送が起きるし、ほとんどのHTTP通信ではパケットが順番どおりに到着しないとUIが更新されない。実際、単一のRESTリクエストであっても、リクエストとレスポンスが1400バイト未満のときにだけ本当に1パケットで処理される。それを超えると「単一」のリクエストも実際には複数のパケットに分割される。このうちどれか1つでも問題があると、すべてのパケットが順番どおりに到着しなければ画面は正しく更新されない。試してみたければ、Chrome開発者ツールで3Gモードとパケット損失を有効にしてテストすれば、小さな最適化ひとつでもUIの応答性が大きく改善するのが分かる。だからAPIとUIをできるだけ小さくするのには十分な説得力がある
自分のホームページの転送量は圧縮後で7.0kB
14kB目標はやや挑戦的だが、初期10パケット以内に制限するという考え方は面白い。自分のようにWebサイトのサイズに注目するプロジェクトとして 512kb.club がある。サイトサイズをゴルフスコアのように比較する場所だ。自分のサイト(anderegg.ca)は登録前に全リソース合計71kBだった。このプロジェクトのおかげで Cloudflare Radar も知ったが、サイト分析やページサイズ測定に良いツールがある。主目的はインターネット全体のダッシュボードだが、ページサイズ分析ツールも含まれている
これをもう少し面白く実験したいなら、初期ウィンドウ(IW)サイズはサーバー側で設定できる。たとえば次のように変更可能だ
以下の記事で説明されている内容も当てはまる: Cloudflareブログ - ロシアのISPが16KBまでしか許可せず、ほとんどのWebブラウジングが不可能になった現象。Cloudflareの分析によれば、ロシアのISPは国内ユーザーへのインターネットスロットリングによって、Webアセットごとに最初の16KBまでしか読み込めないよう制限している
TCP Slow Startが何かを知らない人と、Webサイトの読み込み遅延を細かいところまで気にするほど関心のある人の交差はごく小さい。スタートアップはまずスタートアップに集中すべきで、こういう最適化に執着できる余裕があるのは大企業だけだ
自分のホームページは17.2KBだ!(依存関係を除く) 個人ページとして本気で最適化して、Lighthouse満点100も達成した。以前は不可能だと思っていたが成功した。ちなみにRailsで作った。こういう最適化は実際やる価値がある。もたつき感なく稲妻のように表示されるページ体験は、それ自体がとても満足感が高い
この文章には論理的な弱点が2つあると思う
最近の世代は、単純な静的WebサイトですらNext.jsのようなフレームワークで作る傾向がある。HTML+CSS+jsの時代が終わっていくようで残念だ
遅延だけでなく、資源消費の最小化は持続可能な未来に不可欠な条件だ。ネットワークが環境に与える影響も決して小さくない。コメント欄の空気がやや皮肉っぽいのは残念だ。この最適化が究極の解決策である時代ではないとしても、エネルギー使用量削減の効果がもっと強調されてもよいと思う