ページの表示速度:サイト読み込み最適化の総合ガイド

サーバー応答、読み込み、レンダリング、操作への反応を切り分けて原因を特定し、フィールドデータとラボデータで改善を確認する方法を解説します。

ページの表示速度への投資は、SEOとコンバージョンの両方に大きく効く施策の一つです。Amazonの試算では、遅延が100ミリ秒増えるごとに売上の1%を失います。Googleはデスクトップでは2010年から、モバイルでは2018年から速度をランキング要因に使っています。2021年にはCore Web Vitalsをページエクスペリエンスの直接のシグナルとして導入しました。

読み込みのウォーターフォール。リソースは順に要求され、遅延が起きるたびにLCPが後ろへずれていきます。
モバイルユーザーの53%は、読み込みに3秒以上かかるページから離脱します。ECサイトでは、商品が1つも表示されないうちにコンバージョンを失うことになります。

ページの表示速度とは、どう測るか

ページの表示速度は1つの数値ではありません。読み込み体験の異なる側面を測る指標の集合です。GoogleのPageSpeed Insightsは、ラボデータ(Lighthouse)と実ユーザーのフィールドデータ(Chrome User Experience Report)を組み合わせて表示します。0〜100の最終スコアは複数の指標の加重合計で、これだけを最適化の目標にするのは避けてください。

SEOで重要なのはフィールドデータ(CrUX)です。GoogleはCore Web Vitalsの評価に、実際のChromeユーザーの75パーセンタイルを使います。Lighthouseは問題の診断には役立ちますが、ランキングアルゴリズムへの直接の入力ではありません。

主要な速度指標

各指標は、ユーザー体験の特定の側面を扱います。違いを理解することが、正しい診断の土台になります。

指標測定する内容良好な値ランキングへの影響
TTFB(最初のバイトまでの時間)サーバーからHTMLの最初の1バイトが届くまでの時間< 800ミリ秒間接的(LCP経由)
FCP(First Contentful Paint)コンテンツの最初の1ピクセルが画面に表示されるまで< 1.8秒Lighthouseの指標。CrUXの評価対象ではない
LCP(Largest Contentful Paint)メインコンテンツがユーザーに見えるまで< 2.5秒あり(Core Web Vitals)
INP(次の描画までの操作遅延)ユーザー操作への応答性< 200ミリ秒あり(Core Web Vitals。FIDの後継)
CLS(Cumulative Layout Shift)レイアウトの安定性。要素がどれだけずれるか< 0.1あり(Core Web Vitals)
TBT(Total Blocking Time)JSによるメインスレッドのブロック時間の合計< 200ミリ秒INPのラボ上の代替指標
FID(First Input Delay)は、2024年3月にINP(Interaction to Next Paint)へ正式に置き換わりました。使っているツールがまだFIDを報告する場合は、ツールを更新するか、その指標を無視します。INPは最初の操作だけでなく、すべての操作の遅延を測ります。
53%

3秒以内に離脱

読み込みに3秒以上かかるページから離脱するモバイルユーザーの割合

1〜3%

1秒あたりのコンバージョン

遅延が1秒増えるごとに、コンバージョンは平均で1〜3%下がる

75th

CrUXのパーセンタイル

GoogleはCore Web Vitalsを実ユーザーの75パーセンタイルで評価する

28日

CrUXの集計期間

サイト評価のためにデータを集める移動期間

診断:最適化はどこから始めるか

当てずっぽうの最適化は無駄な作業です。正しい順序は、測定し、ボトルネックを特定し、修正し、もう一度測定することです。

  1. PageSpeed Insightsを開き、主要なページを5〜10件テストします。トップページ、カテゴリ、商品ページ、ランディングページなどです。Lighthouseのスコアだけでなく、フィールドデータを見ます。
  2. Google Search ConsoleのCore Web Vitalsを開きます。LCP、INP、CLSで「不良」または「改善が必要」と評価されたURLが、実ユーザーのデータで分かります。
  3. WebPageTestで詳しく分析します。読み込みのウォーターフォール、フィルムストリップ、TTFB、CDNの影響を確認します。テスト地域は、主な読者に最も近い場所を選びます。
  4. Chrome DevToolsの「Performance」でページの読み込みを記録します。フレームチャートを見ると、どのスクリプトがメインスレッドを占有し、レンダリングをブロックしているか分かります。
  5. Coverage(DevTools → Coverage)を確認します。未使用のCSS/JSは、削除または遅延読み込みの直接の候補です。
テストにはシークレットモードを使い、ブラウザー拡張機能を無効にします。広告ブロッカーなどの拡張機能は結果を歪めます。再現性のある結果が必要なときは、Lighthouse CLIかWebPageTestを使います。

PageSpeed Insights

Googleの無料ツールです。ラボ(Lighthouse)とフィールド(CrUX)の両方のデータを表示します。具体的な改善提案を、見込まれる短縮時間つきで一覧にします。最初の監査の出発点として最適です。

WebPageTest

詳細なウォーターフォール、フィルムストリップ、複数地点でのテスト、バージョン比較ができます。CDN、DNS、SSLハンドシェイクの影響も分かります。TTFBを掘り下げて診断するのに欠かせません。

Google Search Console

URLグループ別の実際のCrUXデータを表示します。指標の推移も追えるため、最適化を反映したあとの改善をモニタリングするのに最適なツールです。

Chrome DevTools

PerformanceプロファイラーとCoverageタブで、レンダリングをブロックしている特定のスクリプトやCSSを探します。フレームチャートで、メインスレッド上のLong Task(50ミリ秒超)が分かります。

サーバーとTTFBの最適化

TTFB(Time to First Byte)は、あらゆる速度の土台です。サーバーの応答が遅いと、その後の最適化はすべて、人為的な上限の下で働くことになります。目標は、CDN環境でTTFB < 200ミリ秒、動的サーバーで < 400ミリ秒です。

ホスティングとインフラ

ホスティングの選択
数千のサイトでリソースを分け合う共用ホスティングでは、TTFBに物理的な限界があります。Nginx/Caddyと適切なキャッシュを備えたVPSや専用サーバーなら、静的コンテンツのTTFBは20〜80ミリ秒になります。
CDN(Content Delivery Network)
Cloudflare、BunnyCDN、Fastlyなどでは、オリジンサーバーの代わりに最寄りのエッジノードが応答します。静的コンテンツやキャッシュ済みコンテンツのTTFBは10〜50ミリ秒に下がります。動的コンテンツでは、エッジキャッシュの設定次第です。
HTTP/2とHTTP/3(QUIC)
HTTP/2はヘッドオブラインブロッキングを解消し、多重化に対応します。QUICを使うHTTP/3は、接続の確立(0-RTT)をさらに速め、モバイル回線でのパケットロスにも強い方式です。
サーバーの地理的な位置
ユーザーとサーバーの物理的な距離により、往復で100kmあたり約1ミリ秒かかります。ヨーロッパの読者が中心なら、フランクフルトやアムステルダムのサーバーは、米国東部よりかなり速くなります。

圧縮とエンコーディング

  • Brotli(br)を有効にします。gzipと比べて15〜25%小さくなり、展開速度は同程度です。最新のブラウザーはすべて対応しています。
  • 古いクライアント向けのフォールバックとして、gzipも残します。圧縮レベルは6以上にします。
  • 圧縮はHTML、CSS、JS、JSON、XML、SVGに設定します。画像やバイナリーファイルはすでに圧縮されており、gzipをかけても効果はありません。
  • Vary: Accept-Encodingヘッダーを付けます。CDNがクライアントごとに別のバージョンをキャッシュできるようになります。

サーバーサイドのキャッシュ

動的ページ(PHP、Node.js、Python)は、リクエストのたびにデータベースにアクセスします。キャッシュを使うと、再計算せずに生成済みのHTMLを返せます。

  • フルページキャッシュ:Nginx FastCGI Cache、Varnish、Redisなどで生成済みHTMLを保存し、アプリケーションを通さずに返します。
  • オブジェクトキャッシュ:RedisやMemcachedで、データベースのクエリ結果、セッション、計算済みデータをキャッシュします。
  • 無効化のルール:コンテンツが変わったらキャッシュを消去します(CMSのWebhook、TTLによる期限切れなど)。
  • Stale-while-revalidate:古いキャッシュをすぐに返し、裏で再生成します。ユーザーは再生成を待たずに済みます。
Next.jsでは、ISR(Incremental Static Regeneration)が、stale-while-revalidateの組み込み機構にあたります。ページは一度だけ生成され、revalidate: N秒の設定に従って裏で更新されます。TTFBは静的ファイル並みに速く、データも新鮮に保てます。

アセットの最適化:画像、フォント、CSS

画像

画像は、ページの転送量で最も重い要素になるのが一般的です。正しく最適化すれば転送量を30〜70%削減でき、LCPにも直接効きます。

手法削減効果優先度
JPEG/PNGの代わりにWebP25〜35%高
JPEG/PNGの代わりにAVIF40〜55%高(ブラウザー対応率90%以上)
可逆圧縮(PNG → oxipng)5〜20%中
適切なサイズ指定(srcset + sizes)モバイルで50〜80%高
画面外の画像の遅延読み込み読み込み時のリクエストを節約高
LCP画像へのfetchpriority="high"LCPが0.5〜1.5秒改善最重要

<picture>要素で、適切な形式を出し分けます。対応ブラウザーにはAVIF、フォールバックにWebP、古いブラウザーにはJPEG/PNGです。Next.jsのImageコンポーネントなら、これを自動で処理します。

フォント

  • フォントをセルフホストします。.woff2を自社ドメインから配信すると、DNSルックアップとTCPハンドシェイクが不要になり、Google FontsのCDNへの依存もなくなります。
  • 重要なフォントをプリロードします。<head>に<link rel="preload" as="font" type="font/woff2" crossorigin>を入れると、CSSの解析前に読み込みが始まります。
  • font-display: swapを指定します。カスタムフォントの読み込み中は、システムフォントで表示します。FOIT(テキストが見えない状態)を防げます。
  • フォントをサブセット化します。必要なグリフ(ラテン文字 + キリル文字)だけを読み込みます。ツールはglyphhangerかfonttoolsです。
  • 可変フォントを使います。ウェイト(標準、太字、斜体)ごとの複数ファイルが1つで済み、フォント全体のサイズを30〜50%減らせます。

CSS

クリティカルCSSのインライン化
ファーストビューのスタイルを、<head>内の<style>タグに直接埋め込みます。ブラウザーは外部CSSファイルを待たずに最初の画面を描画できます。残りのCSSは非同期で読み込みます。
最小化(minify)
空白とコメントを削除し、プロパティを短縮します。CssnanoやLightningCSSを使います。削減の目安は元のサイズの10〜30%です。
未使用CSSの削除
PurgeCSS、UnCSS、またはフレームワーク組み込みの仕組み(Tailwindのpurge)を使います。BootstrapやMaterial UIを使う場合は特に重要です。数千もの未使用ルールを取り込んでしまうためです。
CSSの@importを避ける
CSSの@importは、リクエストを連鎖させます。ブラウザーはファイルを読み込んで@importを見つけ、そこで初めて次のファイルの読み込みを始めます。並列で読み込めるよう、<link>タグを使います。

JavaScript:レンダリングブロックとメインスレッド

JavaScriptは、現代のサイトでページの表示速度を最も損なう要因です。レンダリングをブロックし、メインスレッドを占有し、操作できるようになるまでの時間を遅らせます。目標は、クリティカルパス上のJSを最小限にし、defer/async/動的importを最大限に使うことです。

読み込み戦略

属性動作使う場面
なしHTMLの解析をブロックし、すぐに実行される重要なインラインコードのみ
async並列で読み込み、準備ができ次第実行(解析を中断することがある)独立したスクリプト(アナリティクスなど)
defer並列で読み込み、HTMLの解析後に実行ページ上のほとんどのスクリプト
type="module"デフォルトで遅延実行 + ESM対応最新のESMスクリプト

バンドルとコード分割

  • コード分割:JSをチャンクに分け、現在のページに必要なものだけを読み込みます。Next.jsではページごとに自動で行われます。
  • 動的import:初回表示で不要なコンポーネント(モーダル、タブ、フィルターなど)には、import('module')を使います。
  • ツリーシェイキング:実際に使うコードだけをバンドルします。WebpackとRollupは、ESMパッケージに対してこれを行います。ツリーシェイキングを妨げるCommonJSの依存がないか確認します。
  • バンドルの分析:npmパッケージのサイズはbundlephobia.comで確認します。Next.jsなら@next/bundle-analyzerで、何が容量を占めているかが正確に分かります。
  • 大きな一枚岩のライブラリを避けます。moment.js(67KB)はday.js(2KB)に、lodashは個別のユーティリティに、jQueryはネイティブJSに置き換えます。
Long Task、つまり50ミリ秒を超えるメインスレッドのタスクは、INPが悪化する直接の原因です。DevToolsの「Performance」で確認します。よくある原因は、大きなJSONの解析、localStorageへの同期アクセス、負荷の高いReactの再レンダリングです。

SPAとサーバーレンダリング

クライアントサイドのSPA(SSRなしのReact、Angular、CSRのVue)は、空のHTMLを返し、コンテンツをブラウザーで生成します。その結果、LCPが高くなり、Time to Interactiveも悪化します。

SSR(Server-Side Rendering)
完全なHTMLをサーバーで生成します。ブラウザーは完成したコンテンツをすぐに受け取れます。LCP、FCP、Lighthouseスコアのすべてが大きく改善します。クライアント側のハイドレーションが必要なため、TTI(Time to Interactive)を考慮します。
SSG(Static Site Generation)
HTMLをビルド時に生成します。TTFBとLCPが最速になります。ブログ、ドキュメント、ランディングページなど、更新頻度の低いコンテンツに向いています。
PPR(Partial Prerendering)
Next.js 15の新機能です。静的なページの骨組みに、動的な部分をストリーミングで流し込みます。静的な骨組みはCDNから即座に配信され、動的データは準備できたものから順に届きます。

キャッシュ:ブラウザーとCDN

正しく設定したキャッシュは、最も低コストで、再訪問ユーザーに最も大きく効く最適化です。目標は、静的アセットをすべて1年キャッシュし、HTMLのキャッシュは最小限、またはなしにすることです。

リソースの種類Cache-Control無効化の方針
ハッシュ付きのJS/CSS(bundle.abc123.js)max-age=31536000, immutableファイルが変わるとハッシュが変わる
画像max-age=2592000(30日)バージョン付きURL、またはContent Hash
HTMLページno-cache、またはmax-age=0, must-revalidate常にサーバーで再検証する
フォントmax-age=31536000, immutableURLにハッシュ、またはバージョン管理
APIレスポンスCache-Control: private, max-age=60データの更新頻度による
  • コンテンツベースのハッシュ化(フィンガープリント):Webpack、Vite、Next.jsは、ファイル名にコンテンツのハッシュを自動で付けます。コードが変わるとハッシュも変わるため、古いキャッシュは使われません。
  • ETagとLast-Modified:クライアントがすでにリソースを持っていれば、サーバーは本文なしで304 Not Modifiedを返します。転送量は減りますが、ネットワークの往復は残ります。
  • Service Worker:ブラウザー内のプログラム可能なキャッシュです。PWAやオフライン対応のために、Cache-First、Network-First、Stale-While-Revalidateなどの高度な戦略を実現できます。
  • CDNのCache-Control:s-maxageで、ブラウザーのmax-ageとは別にCDNのキャッシュを制御します。CDNは長く、ブラウザーは短くキャッシュします。

サードパーティスクリプト:見落とされがちな最大の原因

サードパーティスクリプト(アナリティクス、チャットボット、ピクセル、A/Bテスト、ウィジェット)は、TBTとINPが悪化する主な原因になりがちです。商用ページの平均で、15〜30本のサードパーティスクリプトが読み込まれています。

サードパーティスクリプトの監査

WebPageTestの「Third-party Summary」タブで、どのスクリプトがメインスレッドを何ミリ秒ブロックしているか分かります。典型的な原因は、Intercom、Hotjar、Google Analyticsの古いバージョン(asyncなしのgtag)です。

遅延読み込み

重要でないスクリプトは、loadイベントのあとにsetTimeout(loadScript, 3000)で遅らせて読み込みます。アナリティクスの読み込み前に、ユーザーはページを操作できます。

DNS prefetchとpreconnect

確実に通信するドメインには<link rel="preconnect">を、通信しそうなドメインには<link rel="dns-prefetch">を使います。サードパーティのドメインごとに、DNSルックアップとTCPハンドシェイクで100〜300ミリ秒を節約できます。

置き換えるか、削除する

サードパーティスクリプトの最善の最適化は、削除です。有料のチャットボットは全ページに必要でしょうか。ソーシャルのピクセルは5つ必要でしょうか。実際に使っているスクリプトを棚卸しすると、30〜50%が不要と分かることがよくあります。

Google Tag Managerは便利ですが、危険でもあります。GTMのタグ1つで、マーケティング担当者が開発者のレビューなしに追加した20本のスクリプトを呼び込めます。GTMのコンテナは定期的に監査し、古いタグを削除してください。

FAQ

SEOでより重要なのは、LighthouseスコアとCore Web Vitalsのどちらですか?
SEOでより重要なのは、Core Web Vitals(CrUXのフィールドデータ)です。Googleがランキングアルゴリズムで使うのはこのデータです。Lighthouseスコアは役に立つ診断ツールですが、ランキングへの直接の入力ではありません。Lighthouseが60でもCrUXが良好なサイトは、Lighthouseが95でもフィールドデータが悪いサイトより上位に表示されます。
表示速度を改善すると、どのくらいで順位に反映されますか?
CrUXは28日間の移動期間で更新されます。今日指標を改善しても、Googleでシグナルが完全に切り替わるまで約4週間かかります。順位が急に跳ね上がることは期待できません。改善は徐々に進みます。進捗は、Search ConsoleのCore Web Vitalsで確認します。
Lighthouseのスコアが高いのに、サイトが遅く感じるのはなぜですか?
Lighthouseはラボツールで、固定された設定(通常はMoto G Power、4G)でテストします。実際のユーザーは、低速なスマートフォンや不安定な3G、遠隔地から利用しています。PSIとSearch Consoleでフィールドデータを確認してください。INPも見ます。体感の「もたつき」は、読み込みではなくクリックへの反応の遅さが原因であることがよくあります。
表示速度のためにAMPを使う価値はありますか?
2024〜2026年にかけて、AMPの利点はほとんど失われました。GoogleはAMPページのトップニュースカルーセルでの優先扱いをやめ、Core Web Vitalsを共通の基準にしました。LCPが良好な最適化済みの非AMPページは、AMPと同等に評価されます。推奨は、AMPに投資せず、CWVに投資することです。
表示速度は、デスクトップよりモバイルの順位に強く影響しますか?
はい。Googleは2019年からモバイルファーストインデックスを採用しており、サイトのモバイル版を優先してインデックスし、評価します。モバイルユーザーのCrUXはデスクトップとは別で、数値が悪いことも多くあります。まずモバイルの速度を最適化します。

Check it with SpiderHead

Free and local: run the audit on your own machine.

Try it