圧縮とキャッシュの監査

初回の訪問で何バイト送られ、次の訪問でもう一度何バイト送られるかは、2つのレスポンスヘッダーで決まります。この監査は、あなたのページと、そのサイト自身のファイル最大14個でそれを読み取ります。

例: mozilla.org, wordpress.org

ヘッダーでの短いやり取り

ブラウザーはリクエストのたびに、展開できる圧縮形式を伝えます。

Accept-Encoding: gzip, deflate, br, zstd

圧縮を有効にしたサーバーはそのうち一つを選び、ファイルを縮めて、レスポンスに Content-Encoding: br(Brotli)や gzip と表示します。HTML、CSS、JavaScriptは繰り返しの多いテキストで、通常サイズが70〜85%減ります。JPEG、PNG、WebP、AVIF、WOFF2のファイルは形式自体ですでに圧縮されているので、そのまま送るのが正解です。

もう半分はキャッシュです。Cache-Control: max-age=31536000 があれば、ブラウザーは問い合わせずに1年間ファイルを再利用できます。期間が切れたら、ETag や Last-Modified ヘッダーによって、ブラウザーは「変わりましたか?」という軽い質問ができ、サーバーは本文なしの 304 Not Modified で答えます。

監査するファイル

まずリダイレクト後のページそのものから始め、そのHTMLにある同じ登録ドメインのファイルを取ります。スタイルシート最大4つ、スクリプト5つ、画像3つ、フォント2つです。使われなかった枠は残りのファイルに回し、合計15個まで。余裕があれば、スタイルシート内で参照されているフォントも加えます。各ファイルはブラウザーと同じように、Brotliとgzipを提示し、サーバーが対応していればHTTP/2でリクエストします。

Google Fontsやアクセス解析のスクリプトなど、別のドメインにあるファイルは除外します。そのヘッダーはあなたが設定するものではないからです。

各列の判定基準

圧縮
テキストファイルが Content-Encoding 付きで届けば緑です。ページ、または20 KBを超えるテキストファイルが無圧縮で届けば赤です。それより小さい無圧縮ファイルはオレンジで、1 KB未満のファイルは問題にしません。無圧縮のファイルごとに、監査が自ら内容をgzipで圧縮し、得られるサイズを示します。画像とWOFF2フォントは「不要」と表示します。
キャッシュ
期間は max-age から、max-age がなければ Expires から取ります。スタイルシート、スクリプト、画像、フォントは、期間がないか7日より短い場合に指摘します。no-store と no-cache はゼロとみなします。HTMLのページは参考として表示するだけですが、1時間を超えて保持される可能性があれば注意を出します。再訪問者が古い版を見ることになりかねないからです。
プロトコル
すべてのファイルを一つの接続で並行して運ぶHTTP/2なら合格です。HTTP/3は、サーバーが h3 を告知する alt-svc ヘッダーで検出します。
削減量
サンプル全体の、転送バイト数と展開後のバイト数の比較です。

どこでもgzipを使っているサイトには、Brotliについての注記が出ます。Brotliはテキストファイルをおよそ15〜20%小さくします。計画的に取り入れる改善と考えてください。なくても問題はありません。

安全な設定方法

直すべき点があれば、結果にApacheとnginx用の設定例が付きます。CloudflareなどのCDNの背後では、圧縮はエッジで行われ、キャッシュ期間は管理画面の設定です。WordPressでは、キャッシュ系のプラグインが同じルールを書いてくれます。

期間については、一つのルールですべてが決まります。長いキャッシュが安全なのは、内容が変わるたびにファイルのアドレスも変わる場合だけです。ビルドツールは app.3f9a1c.js のような名前を作り、WordPressは ?ver=6.8 を付け加えます。こうしたファイルには次のように設定できます。

Cache-Control: public, max-age=31536000, immutable

名前が固定のファイルは、1週間から1か月にしておくのが無難です。HTMLには、Cache-Control: no-cache にすればコピーを保持しつつ、使うたびにサーバーに確認します。

名前に反して、no-cache は「使う前に再検証する」という意味です。コピーの保持を禁じるディレクティブは no-store で、個人データを含むページに使います。

ターミナルから変更を確認するには:

curl -sI -H "Accept-Encoding: br, gzip" https://example.com/ | grep -iE "content-encoding|cache-control"

監査で扱わないもの

一つのページから15ファイルを抜き出したサンプルなので、別のテンプレートにだけある問題は見逃すことがあります。Zstandardは提示しません。max-age を読み、共有キャッシュだけに関係する s-maxage は無視します。また、自社のCDNが別のドメインから配信するファイルは対象外です。各ファイルは最大3 MBまでダウンロードします。

よくある質問

サイトでgzipやBrotliが有効か確認するには?

Accept-Encoding ヘッダー付きでページをリクエストし、レスポンスに Content-Encoding があるか見てください。この監査はそれをページと主なファイルに対して行い、上の curl コマンドは一つのアドレスに対して行います。

Brotliはgzipより優れていますか?

テキストなら、はい。ファイルはおよそ15〜20%小さくなり、現在のすべてのブラウザーがHTTPS経由で受け付けます。gzipは今も十分な基準で、古いクライアント向けの代替手段です。サーバーでは通常、両方を有効にします。

CSSとJavaScriptにはどのCache-Controlを使うべきですか?

リリースのたびにファイル名やクエリ文字列が変わるなら、public, max-age=31536000, immutable です。名前が変わらないなら、1週間などの短い期間にしてください。そうしないと、更新後も訪問者に古い版が残ります。

画像もgzipで圧縮すべきですか?

いいえ。JPEG、PNG、WebP、AVIFはすでに圧縮されており、gzipはプロセッサーの時間を使ってもほとんど何も減らしません。例外はSVGで、テキストなのでとてもよく圧縮できます。

表に一部のファイルがないのはなぜですか?

確認するのはページと同じ登録ドメインのファイルだけで、最大15個です。別のドメインから配信されるファイルや、スクリプトがあとから読み込むファイルは、サンプルに含まれません。

HTTP/3は必要ですか?

大事なのはHTTP/2で、ほぼすべてのホスティングが提供しています。HTTP/3は主に不安定なモバイル回線で役立ちます。一番簡単な導入方法は、標準で有効にしているCDNを使うことです。