サイトの表示速度は、画像の重さ、キャッシュの設定、JavaScriptの読み込み順、サーバーの応答時間の4か所でほぼ決まります。この記事では、改善前にLighthouseとcurlで遅い区間を数値で押さえ、効き目の大きい順に直す手順を、コマンドと設定例つきで解説する内容です。WebPへの変換、fetchpriorityの付け方、nginxのCache-Controlとgzip、deferとasyncの使い分けまで、2026年10月時点の公式ドキュメントにもとづいて扱います。
まとめ:サイトの表示速度改善は計測で原因を決めてから画像・キャッシュ・JSの順に直す
最初にやるのは計測です。Lighthouseでページ全体の重さとLCP、curlでサーバーの応答時間(TTFB)を測り、どの区間が長いかを決めてから手を付けます。TTFBが0.8秒を超えるならサーバー側、超えないなら画像とフロントエンドが主な原因です。
直す順番は、手間に対して効き目が大きい順に「画像の変換と寸法指定」「静的ファイルのキャッシュと圧縮」「JavaScriptとWebフォントの読み込み順」「リダイレクトとページ生成の短縮」です。最初の2つはHTMLとサーバー設定の変更で済みます。テーマや画面の作り直しが要るのは後半の2つで、ここから先は工数と流入の見込みを比べて判断します。
改善前の計測:LighthouseのCLIとcurlで遅い区間を数値で押さえる手順
計測を飛ばして画像圧縮から始めると、原因がサーバーにあった場合に工数が無駄になります。同じ条件で改善前の値を残しておけば、効き目の確認にもそのまま使える比較基準です。合否に使われるCore Web Vitalsのしきい値と、ラボ値と実データの違いはCore Web Vitalsとは:LCP・INP・CLSの基準値とweb-vitals・CrUX APIでの測り方【2026年10月】で解説しています。
Lighthouse 13.5系をCLIで実行しLCPと転送量をJSONで取り出す手順
ブラウザの画面で測ると、拡張機能や開いているタブの影響で値がぶれます。LighthouseのGitHubリポジトリにあるCLIを使えば、同じ条件で何度でも測れます。2026年10月時点のnpmの最新版は13.5.0(2026年9月18日公開)で、Node.js 22以上が必要です。
npm install -g lighthouse
# 性能カテゴリだけを、ヘッドレスのChromeで測ってJSONに保存する(既定はモバイル相当の条件)
lighthouse https://www.example.com/ --only-categories=performance \
--output=json --output-path=./before.json --quiet --chrome-flags="--headless"
# 点数・LCP・TBT・CLS・総転送量だけを取り出す
jq '{score: .categories.performance.score,
lcp_ms: .audits["largest-contentful-paint"].numericValue,
tbt_ms: .audits["total-blocking-time"].numericValue,
cls: .audits["cumulative-layout-shift"].numericValue,
bytes: .audits["total-byte-weight"].numericValue}' before.json
PCの条件で測るときは--preset=desktopを付けます。1回の値は回線やCPUの空き具合で上下するので、3回測って中央値を残すと比較が安定します。bytesが数MBあるページは、まず画像を疑ってください。
curlの-wオプションでTTFBを測り0.8秒を超えるかでサーバーを疑う判断
サーバーの応答時間は、ブラウザを使わずcurlで切り出せます。time_starttransferが最初の1バイトを受け取るまでの秒数、つまりTTFBです。
curl -s -o /dev/null -H "Accept-Encoding: br, gzip" \
-w "DNS:%{time_namelookup} 接続:%{time_connect} TLS:%{time_appconnect} TTFB:%{time_starttransfer} 合計:%{time_total} 転送:%{size_download}バイト\n" \
https://www.example.com/
TTFBの改善を扱うweb.devの公式記事は、多くのサイトの目安を0.8秒以下、1.8秒超を不良としています。web.devのLCPの改善ガイドでは、LCPのうちTTFBが占める割合の目安を約40%としており、TTFBが1.5秒あるとLCPの2.5秒はほぼ届きません。この場合は画像より先に、後半のサーバー側の作業へ進みます。
画像の軽量化:WebPとAVIFへの変換と寸法指定でページの転送量を減らす作業
多くのサイトで転送量の大半は画像です。変換と縮小はHTMLの構造を変えずにできるので、最初に片付けます。
cwebpで品質75を基準にWebPへ変換し表示幅に合わせて縮小するコマンド
MDNの画像形式ガイドによると、非可逆のWebPは同程度の圧縮のJPEGより25〜35%小さく、AVIFは同等の画質でJPEGより約50%小さくなります。Googleが配布するcwebpの公式リファレンスでは、品質-qの既定値は75で、-resizeの片方に0を渡すと縦横比を保って縮小します。
# 幅1200pxに縮小し、品質75でWebPを書き出す(高さは縦横比から自動計算)
cwebp -q 75 -resize 1200 0 hero.jpg -o hero.webp
# フォルダ内のJPEGをまとめて変換する
for f in images/*.jpg; do
cwebp -q 75 -resize 1200 0 "$f" -o "${f%.jpg}.webp"
done
効くのは形式の変換より縮小のほうです。表示幅が600pxの枠に4000pxの写真を入れていれば、それだけで画素数は40倍を超えます。品質は75から始め、文字入りの画像で滲みが見えたときだけ上げます。
pictureでのAVIF・WebPの出し分けと画像の寸法指定による枠の確保
HTMLではwidthとheightを書いて画像の枠を確保します。
AVIFはChrome 85・Firefox 93・Safari 16.1から対応しており、MDNは代替形式を<picture>要素で用意するよう案内しています。ブラウザは上の<source>から順に対応する形式を選び、どれにも対応しなければ<img>のJPEGを読みます。
<picture>
<source srcset="/img/hero-1200.avif" type="image/avif">
<source srcset="/img/hero-1200.webp" type="image/webp">
<img src="/img/hero-1200.jpg" width="1200" height="630" alt="サービスの利用イメージ" fetchpriority="high">
</picture>
<!-- ファーストビューより下の画像だけを遅延読み込みにする -->
<img src="/img/case-01.webp" width="600" height="400" alt="導入事例の画面" loading="lazy">
widthとheightは表示サイズではなく縦横比をブラウザに伝えるための値で、CSSで幅を100%にしても枠は先に確保されます。書き忘れると、画像の読み込み後に本文が押し下げられてCLSが悪化します。
loading=”lazy”の適用範囲とLCP画像のfetchpriorityの判断
ブラウザの遅延読み込みを解説した公式記事によると、Chromeは画面から高速回線で1250px、低速回線で2500px手前まで来た画像を読み込み始め、この距離は変更できません。同じ記事は、読み込み時に画面に入る画像、とくにLCPの画像にはloading="lazy"を付けないよう注意しています。
よくある失敗は、全画像に一括で遅延読み込みを付けてファーストビューの大きな画像まで遅らせることです。逆にLCPの画像にはfetchpriority="high"を付けて先に取らせます。Fetch Priority APIの公式解説ではGoogle FlightsのLCPが2.6秒から1.9秒に縮んだ例が紹介され、対応はChrome 102・Firefox 132・Safari 17.2からです。付けるのは1ページに1〜2枚までにします。全部に付けると優先度の差が消えます。
キャッシュと圧縮の設定:Cache-Controlとgzipで初回と再訪の転送を削る作業
キャッシュは再訪時とページ移動時の転送を、圧縮は初回の転送を減らします。どちらもサーバー設定の数行で済みます。
ハッシュ付きの静的ファイルは1年・HTMLはno-cacheにするnginxの設定例
HTTPキャッシュを解説したweb.devの公式記事は、ファイル名に版やハッシュを含み中身が変わらないURLにはmax-age=31536000(1年)を付け、版を持たないHTMLにはno-cacheを付けて毎回サーバーに確認させる構成を勧めています。no-cacheは「保存しない」ではなく「使う前に確認する」の意味で、変更が無ければ本文を送らない304応答で済みます。
# ファイル名にハッシュを含む静的ファイル(例: app.3f9a1c2e.js)は1年キャッシュさせる
location ~* \.[0-9a-f]{8,}\.(js|css|woff2|webp|avif)$ {
add_header Cache-Control "public, max-age=31536000, immutable";
}
# HTMLは毎回サーバーに確認させる。更新がすぐ反映され、変更が無ければ304で返る
location ~* \.html$ {
add_header Cache-Control "no-cache";
}
ハッシュの無いstyle.cssに1年のキャッシュを付けると、CSSを直しても再訪者の画面が古いまま残ります。ビルドツールでファイル名にハッシュを付けられない場合は、max-ageを数時間から1日に留めます。
gzipの既定値が無効でtext/htmlしか圧縮しない点とgzip_typesの追記
nginxのgzipモジュールの公式文書では、gzipの既定値はoff、gzip_typesの既定値はtext/htmlだけです。有効にしてもCSSとJavaScriptは種類を足さない限り圧縮されません。
gzip on;
gzip_types text/css application/javascript application/json image/svg+xml;
gzip_min_length 1000; # 既定は20バイト。小さい応答は圧縮しても縮まない
gzip_comp_level 5; # 既定は1(範囲は1〜9)
gzip_vary on; # CDNが圧縮版と非圧縮版を取り違えないようVaryを付ける
設定後は、前の章のcurlの転送の値とcurl -sIで返るContent-Encodingの行で効いているかを確かめます。JPEGやWebPはすでに圧縮された形式なので、gzip_typesに足しても縮みません。
CDNでHTML以外を配信元から切り離すときに確かめるヘッダー
海外や遠方の利用者が多いサイトでは、静的ファイルをCDNの拠点から返すと接続にかかる時間が縮みます。CDNは配信元のCache-Controlに従ってキャッシュする設定が一般的なので、先に上の2つを整えておけば、移行時に触るのはCDN側の設定だけです。キャッシュのキーや無効化の考え方はCDNとは?仕組み・キャッシュ制御からサービスの選び方まで実装目線で解説で扱っています。
JavaScriptとWebフォントの読み込み順:描画を止める処理をdeferで後ろへ回す
画像とキャッシュを整えてもLCPやTBTが長い場合、HTMLの解析をJavaScriptが止めているか、Webフォントの到着待ちで文字が出ていません。
scriptタグにdeferとasyncを付け分けて解析の停止を外す書き方
MDNの<script>要素のリファレンスによると、属性の無いスクリプトは読み込みと実行が終わるまで解析を止めます。deferは解析の完了後に文書の順で実行され、asyncは取得が終わりしだい順序の保証なしに実行されます。type="module"は既定で実行が延期される仕組みです。
<!-- 画面を組み立てる自社スクリプトは defer。書いた順に実行される -->
<script src="/js/vendor.js" defer></script>
<script src="/js/app.js" defer></script>
<!-- 他に依存しない計測タグは async -->
<script src="https://analytics.example.com/tag.js" async></script>
迷ったらdeferにします。asyncを他のスクリプトに依存するファイルに付けると、読み込み順が入れ替わったときだけ動かない不具合になり、再現が難しくなります。
タグマネージャー経由の広告・計測タグを棚卸しして外部接続を減らす手順
Lighthouse 13系のレポートでは、インサイトのサードパーティの項目(third-parties-insight)に外部ドメインごとの転送量とメインスレッドの占有時間が並びます。上位から順に、今も使っているか、担当者は誰かを確かめ、使っていない広告や過去のA/Bテストのタグを止めてください。残すタグの配信元にはpreconnectを書いて接続を先に済ませます。
サードパーティのJavaScriptを扱う公式記事は、早期の接続で100〜500ミリ秒縮むとする一方、10秒使われなかった接続はブラウザが閉じると書いています。preconnectは確実に使う2〜3の配信元だけに付けます。操作への応答の遅さ(INP)が問題なら、区間の切り分け方をINPとは?Core Web Vitalsの応答性指標の基準値と3区間・改善手順で確認してください。
Webフォントのfont-displayとWOFF2・サブセットによる表示短縮の設定
日本語のWebフォントは1書体で数MBになることがあり、届くまで本文が見えないページもあります。フォントの扱いを解説した公式記事は、font-display: swapが文字の表示を最も遅らせない方法で、WOFF2はWOFFより約30%よく圧縮されるとしています。
@font-face {
font-family: "Brand Sans";
src: url("/fonts/brand-sans-subset.woff2") format("woff2");
font-weight: 400;
font-display: swap; /* 届くまでは代替フォントで本文を出す */
}
サイトで使う文字だけに絞るサブセット化をすれば、ファイルは大きく縮みます。見出しだけに使う装飾書体なら、OS標準のフォントに戻すのが最も速い選択です。
サーバー応答の短縮:リダイレクトの削除とページキャッシュでTTFBを縮める作業
計測でTTFBが0.8秒を超えていたら、この章の作業が先です。
同一オリジン内のリダイレクトとHTTPからHTTPSへの転送を消す確認
TTFBの公式記事は、リダイレクトをTTFBが長くなるよくある原因に挙げ、HTTPからHTTPSへの転送はHSTSで避けるよう勧めています。末尾のスラッシュの有無、wwwの有無、HTTPからHTTPSの3つが重なると、本来のページに着く前に3回の往復が入ります。
確認はcurl -sILでLocationの行を数えるだけです。内部リンク・広告の遷移先・canonicalのURLを最終のURLにそろえれば、リダイレクトの多くは消えます。
動的ページの生成時間をページキャッシュと103 Early Hintsで縮める判断
CMSやアプリケーションがアクセスのたびにHTMLを組み立てているなら、生成済みのHTMLを返すページキャッシュが最も効きます。ただしTTFBの公式記事は、キャッシュは遅いバックエンドを隠すとも注意しており、キャッシュを通さない経路の値も別に測っておくべきです。ログイン後の画面やカートはキャッシュできないため、そこが遅ければデータベースの問い合わせの見直しになります。
バックエンドの処理が長いページには、本文の前にCSSなどの読み込みを指示する103 Early Hintsが有効だと同記事は説明しています。WordPressで組んだサイトなら、キャッシュ・OPcache・データベースの整理を順に進めるWordPressの高速化手順:原因の切り分けとキャッシュ・DB・画像の改善【7.1系対応】の手順がそのまま使えます。
受託開発の視点で見る表示速度改善を自社で進める範囲と改修に切り替える条件
ここからは、サイトの改修を受ける立場からの判断です。
設定変更で済む速度改善とテーマや画面の作り直しが要る改善の境目
画像の変換、widthとheightの追記、Cache-Controlとgzipの設定、使っていないタグの停止までは、HTMLとサーバー設定の変更で終わります。社内にサーバーの設定を触れる担当者がいれば、外注せずに進めるべき範囲です。
作り直しが要るのは、テーマが全ページで数百KBのJavaScriptを読み込んでいる、画像のファイル名にハッシュを付ける仕組みが無い、ページの生成に1秒以上かかる、といった場合です。どの画面のどの区間から直すかの洗い出しを任せたい場合は、Webコンサルティング・アクセス解析で計測の設計から改善の優先順位付けまでお受けしています。
見送る場面:Lighthouseの点数だけを追う改修と訪問の少ないサイトの作り込み
月に数百訪問のコーポレートサイトで、Lighthouseの点数を85点から100点に上げるための作り直しは見送ります。実データ(CrUX)が集まらないほど訪問が少ないと、Google側に判定の材料がそもそもありません。その工数は内容や問い合わせ導線に回したほうが成果につながります。
LCPが2.5秒以内に収まっている画面をさらに削る改修も同じ扱いです。例外は、離脱が売上に直結するECの商品一覧や予約フォームで、そこは点数ではなく遅い画面の離脱率で判断します。
サイトの表示速度改善に関するよくある質問と計測方法・設定の答え
表示速度の改善について、検索の多い質問に2026年10月時点の公式ドキュメントをもとに答えます。
ページの表示速度の目安は何秒ですか?
Googleが合否に使う基準では、主要な内容が描画されるまで(LCP)が2.5秒以内なら良好です。よく引用される「3秒」は公式のしきい値ではありません。サーバーの応答(TTFB)は0.8秒以下が目安で、LCPの判定は実利用者の75パーセンタイルで行われます。
表示速度を改善するとSEOの順位は上がりますか?
内容で並んだ競合との間で差が付く程度です。Core Web Vitalsは順位の仕組みが考慮する要素の1つですが、Googleは良い結果でも上位表示は保証されないとしています。順位が目的なら、インデックスやクロールの問題を先に直すほうが効きます。速度の効果は、離脱率やコンバージョン率で見るのが確実です。
無料でサイトの表示速度を測る方法はありますか?
PageSpeed Insightsに URL を入れれば、実データとLighthouseの結果を無料で見られます。繰り返し同じ条件で測るならLighthouseのCLIを、サーバーの応答だけを見るならcurlの-wオプションを使います。どちらも無料で、改善前後の比較に使える計測手段です。
画像はWebPとAVIFのどちらに変換すべきですか?
容量だけならAVIFのほうが小さくなりますが、変換に時間がかかり、対応しないブラウザもあります。まずWebPで全画像をそろえ、ファーストビューの大きな画像だけAVIFも用意して<picture>で出し分ける順が、手間に対して効果が大きい進め方です。
改善してもPageSpeed Insightsの点数が毎回変わるのはなぜですか?
Lighthouseの点数は1回ごとの計測で、回線の状態、計測するマシンの負荷、広告の出方によって上下します。数点の差は誤差とみなし、3回以上測った中央値で比べてください。Search Consoleに出る実データは28日分の集計なので、修正の効き目が表れるまで数週間かかります。
関連記事
- Webパフォーマンス指標の一覧と使い分け|TTFB・FCP・TBT・Speed Indexの基準:計測で出てくる指標の読み方
- LighthouseのSEOスコア・Best Practicesの配点と見方|5カテゴリの採点基準【v13.5.0】:Lighthouseの点数の内訳
- Lighthouse CIの使い方|lighthouserc・assertの判定とGitHub Actions連携【@lhci/cli 0.15.1】:改善した速度をリリースのたびに守る仕組み
- WordPressはオワコンか?シェアと保守コストで採用可否を判断する【2026年9月時点】:CMSの選択が速度と保守に与える影響
- Cloudflare EmDashとは?1.0の変更点・料金・WordPress移行とプラグインの実仕様【1.3.0/2026年10月】:CMSを移す場合の選択肢の1つ