サイト高速化の設定点検|圧縮・キャッシュ・HTTP/2をヘッダーで判定


サイトの高速化は、コードを書き換える前に「サーバーが今どう配信しているか」を1回のリクエストで確かめるところから始まります。レスポンスヘッダーの content-encodingcache-control・HTTPバージョン・画像の content-type という4か所を読めば、転送圧縮・キャッシュ期間・プロトコル・画像フォーマットが現行水準かどうかを、その場で○×で判定できます。

この記事は、高速化の「やることリスト」ではありません。自分のURLを1つ入れてコマンドを打つと、直すべき項目だけが残る点検表です。判定に必要なのは curl だけで、所要は1分もかかりません。サーバーの設定を触れる人はそのまま直しに進めますし、触れない環境の人でも「どこが外れているか」が分かれば管理画面のどの項目を探せばよいかが決まります。

本文に出てくる数値は、すべて2026年8月2日に、公開されているURLへ実際にリクエストして得た結果です。例に使ったURLはどれも誰でも叩けるものなので、同じコマンドを打てば同じ形の答えが返ります(配信側の設定が変われば数値は変わります)。「自分のサイトでは違う値が出た」という状態こそが、この記事で欲しい結果です。


結論|高速化に手を付ける前に、配信設定の4点をヘッダーで判定する

先に判定表を置きます。この記事でやることは、この4行を埋めるところまでです。○が付いた行は読み飛ばして構いません。×が付いた行に対応する章だけ読めば、その日のうちに直せます。

ヘッダーの見る場所合格ライン外れたときに読む章
content-encodingbr / zstd / gzip のいずれかが返っている判定その1・転送圧縮
cache-controlHTMLは短い値、静的アセットは長い値で分かれている判定その2・キャッシュ
HTTPバージョン2 または 31.1 のままでない)判定その3・プロトコル
画像の content-typeブラウザに応じて image/webp 等が返り vary が付く判定その4・画像配信

なぜ配信レイヤーを先に見るのか

高速化の作業は、大きく2つの層に分かれます。ひとつはHTMLやCSSやJavaScriptを書き換える層。もうひとつは、書き換えたファイルをどう包んで、どう届けるかを決める配信の層です。

配信の層を先に見る理由は3つあります。第一に、効果がサイト全体に一律で及びます。圧縮が効いていないサーバーで圧縮を有効にすれば、すべてのページのすべてのテキストファイルが同時に軽くなります。特定のページを直す作業とは効き方の規模が違います。

第二に、判定が一意に決まります。「この画像は軽くすべきか」には人によって答えが割れますが、「content-encoding の行が返っているか」には割れる余地がありません。返っているか、いないかの二択です。

第三に、ここが外れているとコード側の努力が上に乗りません。CSSを苦労して削っても、そのCSSが無圧縮のまま送られていれば、削った分の何倍もの無駄が毎回転送され続けます。後の章で出てくる実測では、あるCSSファイルが158,262バイトから29,922バイトまで縮みました。1行もコードを触らずに、です。

この記事が扱わないこと

範囲を先に切っておきます。以下は意図的に書きません。同じ記事に全部を詰めると、どれも中途半端になるからです。

  • Core Web Vitals(LCP・INP・CLS)の定義と目標値。この記事は指標を1つも扱いません。指標が動く前段にある配信設定の状態だけを見ます
  • PageSpeed InsightsやLighthouseのレポートの読み方。ツール側の画面は一切出てきません
  • HTML・CSS・JavaScriptそのものの最適化(不要コードの削除、クリティカルCSS、リソースヒント)。書き換える側の作業は範囲外です

それぞれの行き先は、最後から2つ目の章「配信設定が全部○なのに遅いとき」でまとめて案内します。

この記事が使わない数字と、Google公式の言い方

高速化の記事でよく見かける「表示が1秒遅れるとコンバージョン率が7%下がる」という数字を、この記事では使いません。執筆時点(2026年8月2日)に出所とされる調査レポートのPDFを探しましたが、公開されている場所に到達できませんでした。現物を確認できない数字を、自分のサイトの設定を決める根拠にする必要はありません。この記事が根拠にするのは、読者が同じコマンドを打てば再現できる実測だけです。

もうひとつ、「Googleは速度をランキング要因にしているので、遅いサイトは検索で不利になる」という書き方もこの記事では取りません。Googleの発表原文はもっと限定的です。2018年のSearch Centralブログは Speed Update について「will only affect pages that deliver the slowest experience to users and will only affect a small percentage of queries」と書いており、影響を受けるのは最も遅い部類のページと、ごく一部のクエリに限られると明示しています。さらに現行のページエクスペリエンスのドキュメントは、FAQで「There is no single signal.」と述べています。

つまり、配信設定を直す動機は「順位が上がるから」ではなく「訪問者の待ち時間と転送量が実際に減るから」です。この記事の合否ラインもそこに置きます。出典はGoogle Search Central Blog「Using page speed in mobile search ranking」Google Search Central「Understanding page experience in Google Search results」(いずれも英語版・2026年8月2日取得)です。


レスポンスヘッダーで分かること|圧縮・キャッシュ・プロトコル・画像形式

ブラウザがサーバーからファイルを受け取るとき、中身(本文)の手前にレスポンスヘッダーという短いテキストが付いてきます。ここには「この中身をどう圧縮したか」「どれだけの間キャッシュしてよいか」「どの形式で返したか」といった、配信側の判断が書かれています。ブラウザはこれを読んで挙動を決めます。

逆に言えば、ヘッダーを読むと配信側の設定がそのまま見えます。管理画面にログインしなくても、サーバーの中を見なくても、外から1回叩けば分かります。この記事で使うのは次の4か所だけです。

見る場所答えてくれる問い外れているときに起きること
content-encodingテキストは圧縮されて送られているかHTML・CSS・JSが数倍のバイト数のまま毎回転送される
cache-control再訪問時に再ダウンロードされるか変わっていないファイルを毎回取り直す、または更新したのに古いまま出る
HTTPバージョン1接続で並行してやり取りできているかリクエスト数が多いページで待ち行列ができる
画像の content-typeブラウザに合わせた形式で返しているか対応ブラウザにも重い方の形式を送り続ける

各ヘッダーの仕様上の定義は、MDNのContent-EncodingCache-ControlAccept-EncodingVary の各ページが一次情報です(2026年8月2日にいずれも到達を確認)。


手順|curl 1コマンドで自分のサイトを判定する

使うのは次の1本です。末尾のURLを自分のサイトのものに差し替えてください。macOSとWindows 10以降には curl が最初から入っています。

curl -sS -D - -o /dev/null \
  -H 'Accept-Encoding: br, gzip, zstd' \
  -w 'http_version=%{http_version} bytes=%{size_download}\n' \
  https://example.com/assets/style.css

オプションの意味は次のとおりです。ここを理解しておくと、結果が想定と違ったときに自分で切り分けられます。

オプション何をしているか省くとどうなるか
-D -レスポンスヘッダーを標準出力へ書き出すヘッダーが見えず判定できない
-o /dev/null本文を捨てる(ヘッダーだけ見たいため)CSSやHTMLの中身が画面に流れて読めない
-H 'Accept-Encoding: …'受け取れる圧縮形式をこちらから宣言するcurlの既定では圧縮を要求せず、無圧縮で返る場合がある
-w '…'HTTPバージョンと転送バイト数を最後に1行で出すプロトコルと実サイズが分からない
-sS進捗表示を消し、エラーだけは表示するプログレスバーが混ざって読みにくい

実際に公開URLへ打った結果です。対象は https://www.php.net/styles/theme-base.css(2026年8月2日実行)。判定に使う行だけ抜き出しています。

HTTP/2 200
content-type: text/css
vary: Accept-Encoding
cache-control: public, max-age=2592000
content-encoding: zstd

http_version=2 bytes=7595

この5行だけで4項目のうち3つが確定します。content-encoding: zstd なので圧縮は○。cache-control: public, max-age=2592000 は静的アセットとして妥当な長さなので○。http_version=2 なのでプロトコルも○。残るは画像だけです。読み方さえ分かれば、判定にかかる時間は数秒です。

curl -I(HEAD)で判定してはいけない

ヘッダーだけ見たいときに curl -I を使う人は多いのですが、圧縮の判定には使えません-I はHEADリクエストを送りますが、HEADに対しては content-encoding を返さないサーバーが実在します。

同じURL(https://web.dev/articles/vitals)に、同じ Accept-Encoding を付けてHEADとGETを1回ずつ投げた結果です(2026年8月2日実行)。

curl -I(HEAD)のとき
HTTP/2 200
content-type: text/html; charset=utf-8
vary: Cookie
cache-control: no-cache, must-revalidate

curl -D - -o /dev/null(GET)のとき
HTTP/2 200
content-type: text/html; charset=utf-8
vary: Cookie
vary: Accept-Encoding
cache-control: no-cache, must-revalidate
content-encoding: gzip

HEADでは content-encoding の行そのものが存在せず、vary: Accept-Encoding も出ていません。GETにすると両方出ます。HEADだけを見て「圧縮されていない」と判定すると、実際には効いているサーバーを不合格にしてしまいます。この記事のコマンドが -D - -o /dev/null という書き方をしているのは、GETのまま本文だけ捨てるためです。

ブラウザの開発者ツールを判定の基準にしない

開発者ツールのネットワークパネルでも同じヘッダーは見えます。ただし判定の基準にするならcurlの方が安全です。ブラウザの表示は、拡張機能・Service Worker・ブラウザ側のキャッシュ・ログイン状態の影響を受けます。「表示されている値」と「サーバーが今返した値」が食い違うことがあり、食い違ったときに原因を切り分けるのが面倒です。

curlはリクエストヘッダーを自分で指定でき、キャッシュも持ちません。条件を固定できるので、同じコマンドを何度打っても同じ条件で比べられます。設定を変えた前後を比較する用途では、この再現性が効きます。


判定その1・転送圧縮|content-encoding が返っているか

合格ラインは単純です。content-encoding の行が返っていれば○、行そのものが無ければ×(無圧縮で配信されている)。ヘッダー名の大文字小文字は区別されないので、Content-Encoding と返ってくるサーバーもあります。目視で探すときも、grepで拾うときも大小を無視してください。

返ってくる値の種類はMDNの Content-Encoding に定義されています。よく見るものを実務上の扱いとあわせて整理します。

アルゴリズム実務上の扱い
gzipLempel-Ziv(LZ77)+32ビットCRC最も広く通る既定値。これが返っていればまず合格
brBrotli(RFC 7932)対応していればgzipより小さくなることが多い
zstdZstandard(RFC 8878)採用例が出てきている。php.netのCSSで実際に返ってきた
deflatezlib(RFC 1950)+deflate(RFC 1951)積極的に選ぶ理由は薄い
compressLZW現在の主要ブラウザではほぼ使われない
dcb / dcz辞書圧縮版のBrotli / ZstandardCompression Dictionary Transport用。通常のサイトでは不要

2026年の記事でgzipだけを挙げるのは不足です。MDNの定義値には brzstd が並んでおり、実際に公開サイトから返ってきます。ただし後述するとおり、gzipを外して新しい方だけに寄せるのは危険です。

実際にどれだけ縮むかを自分で測る

content-encoding が返っているだけでは「効いている」とまでは言えません。同じURLに Accept-Encoding: identity(=圧縮なしで寄こせ)を付けて、バイト数を比べます。圧縮ありの方が明確に小さければ本当に効いています。

curl -sS -o /dev/null -H 'Accept-Encoding: identity' \
  -w 'identity bytes=%{size_download}\n' https://example.com/assets/style.css

curl -sS -o /dev/null -H 'Accept-Encoding: gzip' \
  -w 'gzip     bytes=%{size_download}\n' https://example.com/assets/style.css

公開URL https://s.w.org/style/wp-4-7/css/style.min.css に対して、宣言する形式を変えながら4回叩いた実測です(2026年8月2日)。

送った Accept-Encoding返ってきた content-encoding転送バイト数
identity行なし158,262
gzipgzip31,755
brbr29,922
br, gzip, zstdbr29,925

無圧縮の158,262バイトが、gzipで31,755バイト(約80%減)、Brotliで29,922バイト(約81%減)になりました。この差はコードを1行も触らずに毎回発生します。逆に、圧縮が効いていないサイトは、この差の分だけ毎回余分に送り続けていることになります。

br だけを送って「圧縮されていない」と誤判定しない

ここが最もつまずきやすい点です。Brotliに対応していないサーバーに Accept-Encoding: br だけを送ると、圧縮されずに返ってきます。サーバーは「要求された形式で返せない」ので、無圧縮にフォールバックします。

公開URL https://www.gnu.org/software/bash/manual/bash.html がまさにその状態でした(2026年8月2日実測)。

送った Accept-Encoding返ってきた content-encoding転送バイト数
identity行なし1,040,954
gzipContent-Encoding: gzip196,958
br行なし1,040,954

br だけを要求した回だけ、無圧縮の1,040,954バイトがそのまま返っています。gzipを要求すれば196,958バイトまで縮むので、このサーバーは圧縮そのものは効いていて、Brotliに対応していないだけです。ここで「圧縮されていない」と結論づけるのが典型的な誤判定です。

この事故を避けるための実務ルールは2つです。判定するときは br, gzip, zstd のように複数を並べて送る(実際のブラウザもそう送ります)。そしてサーバー側でBrotliを有効にするときは、gzipを外さずに追加する。gzipを外すと、Brotli非対応の経路(古いプロキシやCDNの一部の設定)で無圧縮に落ちます。

圧縮の対象になるファイルとならないファイル

判定はHTML・CSS・JavaScript・JSON・SVGなどのテキスト系に対して行ってください。JPEG・PNG・WebP・MP4などはすでに圧縮済みのバイナリなので、上からgzipをかけても縮まず、むしろ処理が無駄になります。content-encoding が付いていなくても不合格ではありません。

よくある片手落ちは、HTMLでは content-encoding が返るのに、.css.js では返らないという状態です。これは圧縮対象のMIMEタイプ指定が漏れているサインなので、HTMLだけで判定を終えず、必ずCSSとJavaScriptのURLでも1回ずつ叩いてください。


判定その2・キャッシュ|cache-control をHTMLと静的アセットで読み分ける

cache-control は「何秒に設定すれば正解」という単独の答えがありません。合否は値そのものではなく、HTMLと静的アセットで値が分かれているかどうかで判定します。両方に同じ値が付いているサイトは、たいていどちらかが間違っています。

公開URLを4つ叩いて、返ってきた値を並べたものです(2026年8月2日実測)。

対象返ってきた cache-control読み取れる設計
web.dev の記事HTMLno-cache, must-revalidate保存はしてよいが、使う前に毎回サーバーへ確認させる
s.w.org のCSSmax-age=315360000URLが変わらない限り再取得させない(10年)
php.net のCSSpublic, max-age=2592000共有キャッシュにも30日間の保存を許可
gnu.org のHTMLmax-age=0実質毎回取り直し。HTMLとしては妥当な範囲

HTMLは短く、静的アセットは長い。この対比がはっきり出ていれば○です。なお no-cache は「キャッシュするな」という意味ではありません。MDNは「the response can be stored in caches, but the response must be validated with the origin server before each reuse」と定義しており、保存はするが再利用前に必ず検証するという指示です。「保存させない」のは no-store の方です。

分かれ目は「同じURLで中身が差し替わるか」

長い max-age を付けてよいかどうかの判断基準はひとつです。同じURLのまま中身を差し替える運用をしているなら、長い値を付けてはいけません。更新したのに古いファイルが返り続けます。逆に、内容が変わったらURLも変わる作りなら、いくら長くても事故は起きません。

MDNの Cache-Control も同じことを書いています。「A modern best practice for static resources is to include version/hashes in their URLs, while never modifying the resources」。ファイル名にバージョンやハッシュを含めてURLごと変えるのが前提で、その上で長期キャッシュと immutable が使える、という順番です。順番を逆にして「とりあえず長くする」と、更新が届かない事故になります。

更新したのに古いCSSが表示される状況では、ブラウザ側のキャッシュを消して切り分ける手順が先に必要になることもあります。読者側の操作はスーパーリロードとキャッシュクリアの基本にまとめてあります。ブラウザで消して直るなら配信側の max-age が長すぎるサインで、この章の判定に戻ってきます。

cache-control の行そのものが無いとき

行が返ってこない場合、キャッシュの扱いはブラウザや中間キャッシュの推測に委ねられます。意図した挙動になる保証がないので、静的アセットに cache-control が付いていない状態は×と判定してください。特に、同じサイト内でCSSには付いているのに画像には付いていない、といったばらつきは設定漏れの典型です。判定は1つのURLで終わらせず、HTML・CSS・JS・画像の4種類で1回ずつ叩いて揃っているかを見てください。


判定その3・プロトコル|HTTP/2で話しているか、HTTP/3を出しているか

最初のコマンドの -w 'http_version=%{http_version}' がここで効きます。返ってきた値が 23 なら○、1.1 なら×です。HTTP/1.1では1つの接続で1つのリクエストしか進められないため、読み込むファイル数が多いページほど待ち行列が伸びます。HTTP/2以降は1接続で並行してやり取りできます(MDNのEvolution of HTTPに経緯がまとまっています)。

HTTP/3の提供有無は、レスポンスの alt-svc ヘッダーで分かります。h3=":443" のような値が返っていれば、そのサーバーは「443番ポートでHTTP/3も話せる」と広告していることになります。実測です(2026年8月2日)。

対象http_versionalt-svc
web.dev の記事2h3=":443"; ma=2592000(HTTP/3を提供)
rfc-editor.org のRFC本文2h3=":443"; ma=86400(HTTP/3を提供)
php.net のCSS2行なし
gnu.org のマニュアル1.1行なし

最後の行が×の例です。HTTP/1.1のまま、しかもBrotli非対応という、配信レイヤーが更新されていないサーバーの典型的な見え方になっています。逆に上2つは、プロトコル面では現行水準です。

curl 側がHTTP/3に対応していないことがある

--http3 を付けたら失敗した」ときは、サーバーではなく手元のcurlが原因の可能性があります。HTTP/3対応はビルド時のオプションなので、入っているcurlに機能そのものが無いことがあります。次のコマンドで確認できます。

curl --version

出力の Features: の行に HTTP3 があるかを見てください。手元のmacOS標準のcurl 8.7.1で確認したところ、Features: には HTTP2 は含まれていましたが HTTP3 は含まれていませんでした(2026年8月2日実測)。この環境では --http3 は使えないので、HTTP/3の提供有無は alt-svc で判定するのが確実です。この記事の判定手順が alt-svc を見ているのはそのためです。

HTTP/1.1だったときに見る場所

HTTPバージョンはアプリケーションのコードでは決まりません。Webサーバー本体、その前段のリバースプロキシ、CDNのいずれかの設定で決まります。レンタルサーバーの場合は、コントロールパネルにHTTP/2の有効化スイッチが用意されていることが多いので、まずそこを探してください。CDNを通している場合は、CDN側の設定が優先されるため、オリジンサーバーだけを直しても表からは変わりません。

なお、HTTP/2はTLS(HTTPS)が前提です。HTTPのままのURLで叩けば当然 1.1 が返ります。判定するURLが https:// で始まっていることを先に確認してください。


判定その4・画像配信|同じURLでWebPが返っているかをAcceptで確かめる

拡張子が .png のURLなら、返ってくるのは常にPNGだと思われがちですが、そうとは限りません。サーバーやCDNがリクエストの Accept ヘッダーを見て、返す形式を切り替えていることがあります。この仕組みが働いているかどうかも、curlで確かめられます。

同じ画像URLに対して、Accept だけを変えて2回叩きます。

curl -sS -o /dev/null -H 'Accept: image/avif,image/webp' \
  -w 'type=%{content_type} bytes=%{size_download}\n' https://example.com/img/hero.png

curl -sS -o /dev/null -H 'Accept: image/png' \
  -w 'type=%{content_type} bytes=%{size_download}\n' https://example.com/img/hero.png

公開URL https://i0.wp.com/s.w.org/style/images/about/WordPress-logotype-standard.png で実測した結果です(2026年8月2日)。URLの拡張子は .png のままです。

送った Accept返ってきた content-type転送バイト数
image/avif,image/webpimage/webp23,582
image/pngimage/png30,466

同じURLで、WebPの方が6,884バイト(約22.6%)小さく返ってきました。どちらの応答にも vary: Accept が付いており、「このURLの応答は Accept の内容によって変わる」とキャッシュ側に伝えています。これが無いと、中間キャッシュが最初に受け取った形式を別のブラウザにも配ってしまいます。

合格ラインは「形式が切り替わっている」かつ「vary が付いている」の2つです。切り替わらない場合でも、<picture><source> で明示的にWebPを配っているなら実質的に同じ結果になります。判定したいのは「対応ブラウザにも重い方の形式を送り続けていないか」であって、実現方法は問いません。

削減幅の目安はGoogleが公表しています。Google「WebP – An image format for the Web」は「WebP lossless images are 26% smaller in size compared to PNGs. WebP lossy images are 25-34% smaller than comparable JPEG images at equivalent SSIM quality index.」と書いています(2026年8月2日取得)。上の実測の22.6%はこの範囲に近い値で、公表値と実測が大きく食い違っていないことも同時に確認できます。画像そのものを軽くする側の作業は画像圧縮ツールの選び方にまとめてあります。

遅延読み込みをLCP画像に付けない

画像の話でひとつだけ、配信設定とは別に強く注意しておく点があります。loading="lazy" を全部の <img> に付けるのは誤りです。「付けるだけで初期表示が速くなる」と書かれていることがありますが、ページを開いた時点で画面内に入る画像、とりわけ最大要素として描画される画像に付けると、表示が遅くなります。

web.devの「Browser-level image lazy loading for the web」は注意書きとして「Don’t lazy-load images that are likely to be in-viewport when the page loads, especially LCP images.」と明示しています(2026年8月2日取得)。同じページには「For images that are visible when the user first loads the page, and especially for LCP images, use the browser’s default eager loading」とも書かれています。

実務上の使い分けはこうなります。ファーストビューに入る画像には付けない。スクロールしないと見えない位置の画像にだけ付ける。WordPressのように自動で loading="lazy" を挿入する仕組みを使っている場合は、先頭の画像が除外されているかを実際のHTMLで確認してください。属性の仕様はMDNの<img> 要素のリファレンスにあります。


直したあとの検証|変更が本番に届いたことをヘッダーで確認する

設定を変えたら、変更前とまったく同じコマンドをもう一度打ちます。別のツールに持ち替えないでください。条件が変わると、変わったのが設定なのか測り方なのか分からなくなります。

curl -sS -D - -o /dev/null \
  -H 'Accept-Encoding: br, gzip, zstd' \
  -w 'http_version=%{http_version} bytes=%{size_download}\n' \
  https://example.com/assets/style.css

合否は次の3点で見ます。

見る場所OKNG
content-encodingbr / zstd / gzip のいずれかが返る行そのものが無い(無圧縮で配信されている)
bytes=identity で叩いたときより明確に小さいほぼ同じ(ヘッダーだけ出て実際は効いていない)
http_version=2 または 31.1 のまま

期待どおりにならなかったときの分岐

上から順に潰してください。ここで挙げるのは、実際に誤判定を生みやすい順です。

  1. -I(HEAD)で叩いていないかを確認する。HEADでは content-encoding を返さないサーバーがあるので、GETのまま本文を捨てる形(-D - -o /dev/null)で叩き直す
  2. Accept-Encodingbr だけを書いていないかを確認する。Brotli非対応のサーバーでは無圧縮で返るため、必ず br, gzip, zstd のように複数並べる
  3. HTMLでは返るのに .css.js で返らないなら、圧縮対象のMIMEタイプ・拡張子の指定漏れを疑う
  4. CDNを通しているなら、CDN側のキャッシュを消してから叩き直す。オリジンを直してもエッジに古い応答が残っていると、しばらく前の値が返り続ける
  5. それでも変わらないなら、設定を書いた場所とリクエストが実際に通っている経路がずれている。手前にプロキシやCDNが挟まっていないかを確認する

ここで止める|実ユーザー側の数値はすぐには動かない

ヘッダーが変わったことを確認したら、この記事の検証は終わりです。その足でSearch ConsoleやPageSpeed Insightsの実ユーザーデータを見に行かないでください。変わっていなくて当たり前だからです。

実ユーザー側の数値はChrome User Experience Report(CrUX)が集計元で、これは一定期間の集計値です。Google「About PageSpeed Insights」は「PSI reports real users’ … experiences over the previous 28-day collection period」「Both data sources represent trailing 28-day periods.」と説明しています(2026年8月2日取得)。つまり直近28日間の集計なので、今日直した設定が数値に反映されるまでには時間がかかります。直後に見て「変わらない」と判断すると、正しい変更を巻き戻してしまいます。

この記事の合否は「ヘッダーが変わったところ」までとし、そこから先の指標の追跡は別の記事に渡します。ツール側の画面をどう読むか、スコアが動かないときにどこを疑うかはPageSpeed Insightsの見方と改善実務にまとめてあります。


配信設定が全部○なのに遅いとき|原因が別の層にあるサイン

4項目すべてに○が付いたのに体感が遅い場合、原因は配信の層にはありません。その時点でこの記事の担当は終わりです。症状ごとに、次にどの層を見るべきかを整理します。

症状疑う層この記事の担当か
最初の1バイトが返るまでが長いアプリケーション処理・データベース・オリジンの負荷担当外
ファイルは軽いのに表示が始まらないCSSやJavaScriptの読み込み順・レンダリング阻害担当外
表示途中でレイアウトが飛ぶ画像や広告の寸法指定・後から差し込まれる要素担当外
操作に対する反応が鈍いJavaScriptの実行時間担当外
転送量が大きい・毎回取り直している配信設定(圧縮・キャッシュ)担当

指標の定義と目標値から入り直す

「遅い」を数値で言い直したいなら、指標の側から入るのが早道です。何をどこまで下げれば合格なのか、そもそも何を測っている指標なのかはCore Web Vitalsの3指標と目標値にまとめてあります。この記事は指標を1つも扱っていないので、閾値や測定条件はそちらが正本です。閾値の一次情報はweb.devの「Web Vitals」にあります(2026年8月2日到達確認)。

コードを書き換える側へ移る

配信が整っていて、それでも重いなら、送っているファイルそのものを減らす番です。何から手を付けるか、どこまでやれば十分かの手順はページ速度改善をコードで進める手順にあります。CSSの配送順を変えて初期表示を早める話はクリティカルCSSとインラインCSSの最適化が担当です。

ひとつだけ、古い情報が残りやすい点を補足しておきます。JavaScriptのミニファイツールとして長く挙げられてきた uglify-js は、npmレジストリ上の最新版が 3.19.3(2024年8月29日公開)で、それ以降の更新がありません。同じ日に確認した terser は 5.49.0(2026年7月8日公開)、CSS側の cssnano は 8.0.2(2026年6月11日公開)でした(いずれも2026年8月2日にnpmレジストリで実測)。ツール名を記事から拾うときは、公開日を1回確認してください。

ページ側の作りをまとめて点検する

配信もコードも整っているのに成果が出ないときは、速度以外の要素が原因かもしれません。見出しの構造、メタタグ、構造化データといったページ側の作りをまとめて確認したい場合は、Direbase(ディレベース)にURLを入れると一括で診断できます。この記事の判定がサーバーの外側だけを見ているのに対し、そちらはページの中身を見る道具なので、役割が重なりません。


よくある質問(FAQ)

Q. curlで見るのと、ブラウザの開発者ツールで見るのは同じですか?

どちらも同じレスポンスヘッダーを見ていますが、判定の基準にするならcurlを使ってください。開発者ツールの表示は拡張機能・Service Worker・ブラウザ側のキャッシュ・ログイン状態の影響を受けるため、サーバーが実際に返した値と食い違うことがあります。curlはリクエストヘッダーを自分で指定でき、キャッシュも持たないので、条件を固定した再現可能な判定ができます。

Q. curl -I(HEAD)で確認してはいけないのはなぜですか?

HEADリクエストに対しては content-encoding を返さないサーバーがあるためです。実際にweb.devの記事URLへHEADで問い合わせると content-encoding は返りませんが、同じURLへGETで問い合わせると gzip が返りました(2026年8月2日実測)。圧縮の有無を判定するときは、GETのまま本文だけ捨てる形(curl -sS -D - -o /dev/null)を使ってください。

Q. gzipのままでも問題ありませんか?Brotliに変えるべきですか?

無圧縮なら最優先で直すべきですが、gzipが効いているならまずは合格です。Brotli(br)やZstandard(zstd)はMDNの Content-Encoding に定義された標準の値で、同じ内容をより小さく送れる可能性がありますが、サーバーやCDNの対応が前提になります。対応していないサーバーに br だけを要求すると無圧縮で返ってくるため、gzipを外さずに追加する形で導入してください。

Q. cache-control は何秒に設定すればよいですか?

ファイル名にハッシュやバージョンが付いていて内容が変わればURLも変わる静的アセットは長め、URLが変わらないHTMLは短めにするのが基本です。判断の分かれ目は「同じURLで中身が差し替わるかどうか」で、差し替わるものに長い max-age を付けると、更新したのに古い内容が返り続けます。

Q. 拡張子がpngなのにWebPが返ってくることはありますか?

あります。サーバーやCDNがリクエストの Accept ヘッダーを見て配信形式を切り替えている場合で、このときレスポンスには vary: Accept が付きます。同じURLに対して Accept を変えて2回リクエストすると、content-type と転送バイト数が変わることで確認できます。

Q. すべての画像に loading=”lazy” を付けてよいですか?

付けてはいけません。web.devの遅延読み込みの解説は「Don’t lazy-load images that are likely to be in-viewport when the page loads, especially LCP images.」と明示しており、ページを開いた時点で画面内に入る画像、とりわけ最大要素として描画される画像に付けると表示が遅くなります。スクロールしないと見えない位置の画像にだけ付けてください。

Q. ヘッダーを直したのに、Search Consoleの数値が変わりません。

実ユーザー側のデータ(CrUX)は直近28日間の集計として提供されているため、設定変更の直後には反映されません。この記事の合否はヘッダーが変わったところまでとし、指標そのものの追跡はCore Web Vitalsを扱う記事の側で行ってください。

Q. サーバーの設定を触れないレンタル環境でも改善できますか?

管理画面に圧縮やキャッシュ、HTTP/2の設定項目が用意されていることが多いので、まずそこを確認してください。項目が無い場合でも、画像の枚数と重さを減らす、同じURLで中身を差し替えないファイル名にする、といったアプリケーション側の対策は配信設定に依存せず効きます。


まとめ|点検表を手元に置いて、サイトを触るたびに1回叩く

この記事でやったことは1つです。高速化の作業に入る前に、curlを1回叩いて配信設定が現行水準かを判定する。判定するのは content-encodingcache-control・HTTPバージョン・画像の content-type の4か所だけで、外れた項目に対応する章だけ読めば直せます。

誤判定を生みやすい落とし穴も3つに絞れます。-I(HEAD)で叩かない。br だけを送らない。実ユーザー側の数値を直後に見に行かない。この3つを避ければ、判定結果はそのまま信用できます。

サーバーやCDNの設定、テーマやプラグインの入れ替えは、意図せず配信設定を変えます。だからこの点検は一度きりの作業ではなく、環境を触ったあとに毎回1回打つものとして手元に置いてください。所要は1分もかかりません。

表示速度はサイト品質の一領域にすぎません。ここが片付いたあと、レイアウト・配色・導線・フォームといった他の領域も症状から逆引きして点検したい場合は、作った画面を症状から点検するWebデザインの基本を地図として使ってください。この記事は、その地図のうち「表示速度」の区画を担当しています。

ページ側の見出し・メタタグ・構造化データも診断する