Skip to main content

Core Web Vitals — LCP / INP / CLS から原因を絞る

「サイトが遅い」という報告を受けたとき、どこから調べますか。サーバーのログ、画像のサイズ、JavaScript の量。候補は無数にあります。

Core Web Vitals は、この探索を絞り込むための道具です。3 つの指標がそれぞれ別の原因の系統に対応しているので、どれが悪いかが分かれば疑うべき場所が決まります。定義を覚えることより、組み合わせから原因を導くことのほうが実務では効きます。

この章で学ぶこと

  • 3 指標がそれぞれ何を測っていて、どこから「不良」になるか
  • 指標の組み合わせから原因の系統を絞り込む手順
  • INP がサーバー応答の遅さでは悪化しない理由
  • フィールドデータとラボデータの違い
前提知識

レンダリングパターン のハイドレーションの話が INP の理解に効きます。3 指標がなぜ「メインスレッド」の話になるかは イベントループ が扱います。

この章で扱わないこと

このサイトで実際に LCP と CLS を計測して直した過程は、ブログ記事に記録があります。本章は指標の読み方に絞ります。

3 つの指標と閾値

指標測るもの良好要改善不良
LCP (Largest Contentful Paint)読み込みの速さ2.5 秒以下2.5 〜 4.0 秒4.0 秒超
INP (Interaction to Next Paint)操作への応答性200 ミリ秒以下201 〜 500 ミリ秒500 ミリ秒超
CLS (Cumulative Layout Shift)視覚的な安定性0.1 以下0.1 〜 0.250.25 超

評価は訪問の 75 パーセンタイルで行います。平均ではありません。一部のユーザーだけが極端に遅い状況を平均が覆い隠してしまうためで、「4 人に 3 人は良好な体験ができているか」を見る設計です。

INP は 2024 年に FID (First Input Delay) を置き換えて正式な指標になりました。FID は最初の操作の待ち時間だけを測っていましたが、INP はページ滞在中のすべての操作について、操作から画面が更新されるまでの全体を測ります。

LCP — 主要なコンテンツが見えるまで

ビューポート内で最も大きく描かれた要素 (多くはヒーロー画像か見出しのテキストブロック) が表示されるまでの時間です。

主な悪化要因は次の系統に分かれます。

系統具体例
サーバー応答が遅いデータベースの重いクエリ、キャッシュの不備、遠いオリジン
リソースの読み込みが遅い巨大な画像、圧縮されていない画像、CDN を使っていない
レンダリングがブロックされているhead の同期スクリプト、Web フォントの読み込み方
クライアント側でしか描けないCSR で JavaScript の実行を待たないと主要コンテンツが出ない

**LCP が良好なら、サーバー応答と主要コンテンツの配信は問題ないと判断できます。**ここが後の切り分けで効きます。

INP — 操作してから次の描画まで

ユーザーが操作してから、その結果として画面が更新されるまでの時間です。対象になる操作は クリック・タップ・キー入力の 3 つだけで、スクロールやホバーやズームは含まれません。

INP は 3 つの区間の合計です。

区間何で決まるか
入力遅延メインスレッドが他の処理で塞がっている時間。長いタスクが主因
処理時間イベントハンドラのコールバック自体の実行時間
表示遅延レイアウトの再計算と描画。DOM が大きい、レイアウトが複雑だと伸びる

3 つともブラウザのメインスレッドの話です。ここが重要な点につながります。メインスレッドが 1 本しかなく、長い処理が始まると他が待たされる仕組みは イベントループ にあります。

サーバー応答の遅さは INP の主因にならない

INP が測るのは「次の描画がブロックされている時間」であって、操作後に始まる通信の完了までではありません。ボタンを押して API を叩き、そのレスポンスを待って画面が変わる、という流れでも、INP に計上されるのは押してから次にフレームが描かれるまでです。通信の待ち時間はそこに含まれません。

つまり **INP が不良なら、疑うべきはサーバーではなくクライアントの JavaScript です。**サーバーの遅さは LCP や TTFB (最初の 1 バイトが返るまでの時間) に現れます。

INP を悪化させる典型は次のようなものです。

  • クリックハンドラの中で重い計算や大量の配列処理をしている
  • 巨大な状態更新で画面全体が再レンダリングされる
  • ハイドレーションが終わっていない時間帯に操作された
  • サードパーティのスクリプトがメインスレッドを占有している

CLS — 予期しないずれの累積

ページの読み込み中に要素が勝手に動いた量を累積したスコアです。単位はありません。

スコアは 2 つの割合の積で決まります。

レイアウトシフトのスコア = 影響率 × 距離率
  • 影響率 — ずれた要素がビューポートのどれだけの面積に関わったか
  • 距離率 — 最も大きく動いた距離をビューポートの長辺で割った値

ビューポートの半分を占める要素が高さの 25% 分ずり下がると、影響率 0.75 × 距離率 0.25 = 0.1875 になります。大きい要素が大きく動くほど不利という設計です。

主な原因は 4 つに集約されます。

原因何が起きるか
寸法を指定していない画像・動画読み込み完了まで高さ 0 で、届いた瞬間に下の要素を押し下げる
広告・ウィジェット・埋め込み自分でサイズを変える。読み込みタイミングも読めない
後から挿入されるコンテンツ既存の内容より前に差し込まれると、以降がすべて動く
Web フォント代替フォントと実フォントで文字の大きさが変わり、行の折り返しが変わる

対策の原則は共通しています。**届く前に場所を確保しておく。**画像なら widthheight を属性で指定する (または aspect-ratio を使う)、広告枠なら最小の高さを確保しておく、といった形です。

なお、**ユーザーの操作から 500 ミリ秒以内に起きたずれは計測から除外されます。**ボタンを押してアコーディオンが開くような、ユーザーが予期しているずれを罰しないためです。CLS が問題にするのは「予期しないずれ」だけです。

組み合わせから原因を絞る

ここが実務で最も使う部分です。3 指標は独立した系統に対応しているので、良し悪しの組み合わせが原因の場所を教えてくれます。

LCPINPCLS疑うべきところ
不良良好良好サーバー応答、主要画像の重さ、レンダリングブロック
良好不良良好操作時に走る JavaScript。ハンドラの処理、長いタスク
良好良好不良寸法未指定の遅延コンテンツ。画像、埋め込み、後挿入
不良不良良好JavaScript のバンドルが大きい。読み込みも実行も重い
良好不良不良操作後に DOM を大きく組み替えている
不良良好不良画像まわり全般。重いうえに寸法も指定していない

読み方の例を挙げます。LCP が 1 秒で良好、INP が 520 ミリ秒で不良、CLS が 0.28 で不良という結果が出たとします。

  • LCP が良好 → サーバー応答も主要コンテンツの配信も速い。サーバーは疑わない
  • INP が不良 → 操作時にメインスレッドで重い処理が走っている。クリックハンドラや状態更新を疑う
  • CLS が不良 → 何かが後から届いて既存の内容を押し下げている。遅延読み込みしている画像や埋め込みに寸法指定が無い可能性が高い

この結果から「サーバーサイドの処理が遅いせいでレスポンス待ちが INP に影響している」と結論づけるのは誤りです。INP はサーバーの待ち時間を含みませんし、そもそも LCP が良好である時点でサーバー応答は速いと分かっています。

フィールドデータとラボデータ

同じ指標でも、測り方が 2 通りあります。

フィールドデータラボデータ
何を測るか実ユーザーの実際の体験決められた条件での再現計測
取得元Chrome UX Report、web-vitals ライブラリLighthouse、DevTools
INP の扱い測れる実操作が無いので測れない
用途現状の把握、改善の検証原因の特定、修正前後の比較

**INP はラボデータでは測れません。**実際の操作が必要だからです。Lighthouse のスコアだけを見て「INP は問題ない」と判断できない理由がここにあります。

CLS も注意が要ります。速い回線と速い端末で測ると、遅延読み込みのコンテンツが早く届いてしまい、ずれが再現しないことがあります。ネットワークと CPU を絞った条件で測る必要があります。

よくある誤解

「LCP が良好なら、サイト全体のパフォーマンスに問題はない」 — LCP が保証するのは主要コンテンツの表示までです。操作への応答性 (INP) と視覚的な安定性 (CLS) は別の系統なので、LCP が良くても両方悪いことは普通に起こります。

「INP が悪いのはサーバーが遅いから」 — INP はブラウザのメインスレッドの話で、サーバー応答の待ち時間を含みません。サーバーの遅さは LCP や TTFB に出ます。

「スクロールがカクつくと INP が悪化する」 — INP の対象はクリック・タップ・キー入力の 3 つだけです。スクロールは含まれません。

「CLS はどんなずれでもカウントされる」 — ユーザー操作から 500 ミリ秒以内のずれは除外されます。問題にされるのは予期しないずれだけです。

「Lighthouse のスコアが良ければ Core Web Vitals は良好」 — Lighthouse はラボデータで、INP は測れません。実ユーザーのフィールドデータとは乖離しえます。

確認問題

問 1. LCP 3.8 秒 (要改善)、INP 150 ミリ秒 (良好)、CLS 0.05 (良好) という結果が出ました。まずどこを調べますか。

答え: サーバー応答時間と、主要コンテンツの配信経路。

INP が良好なので、クライアント側の JavaScript は重くありません。CLS も良好なので、後から届いて押し下げるコンテンツもありません。悪いのは LCP だけです。

LCP だけが悪い場合の系統は次の順で調べます。

  1. TTFB — サーバー応答そのものが遅くないか。重いクエリ、キャッシュの不備
  2. 主要要素の配信 — ヒーロー画像が巨大でないか、圧縮されているか、CDN から配られているか
  3. レンダリングブロックhead の同期スクリプトや Web フォントが描画を止めていないか

このサイトでも、Web フォントの読み込み方が LCP を止めていた実例があります。

問 2. 「操作してから API のレスポンスが返るまで 3 秒かかるので INP が悪い」という報告を受けました。妥当ですか。

答え: 妥当ではありません。

INP が測るのは「操作してから次に画面が描かれるまで」です。操作をきっかけに始まる通信の完了までは含みません。API が 3 秒かかっても、押した直後にローディング表示へ切り替わっていれば、その切り替えまでの時間が INP になります。

ただし関連する問題は残ります。押しても何も変わらない状態が 3 秒続くなら、それは UX 上の問題です。INP という指標で捉えるのではなく、押した瞬間にローディング状態を表示する、あるいは楽観的更新で先に結果を見せる、といった設計で解決します。

「指標が悪い」と「体験が悪い」は重なりますが同じではありません。指標が何を測っているかを押さえておかないと、対策が的外れになります。

問 3. CLS が 0.3 で不良です。開発環境の Chrome で確認しても、ずれがまったく再現しません。なぜですか。

答え: 回線と端末が速すぎて、遅延コンテンツが「後から」届いていないためです。

CLS の主因は、後から届いたコンテンツが既存の内容を押し下げることです。開発機と高速な回線では画像も広告も瞬時に届くので、押し下げが起きる前にレイアウトが確定してしまいます。

再現するには計測条件を実ユーザーに近づけます。

  • DevTools のネットワークスロットリング (Slow 4G など)
  • CPU スロットリング (4x〜6x)
  • キャッシュを無効化した状態での再読み込み

そのうえで、遅延読み込みしている画像・広告枠・埋め込みに寸法指定 (width / height または aspect-ratio) があるかを確認します。

まとめ

  • Core Web Vitals は LCP (読み込み)・INP (応答性)・CLS (安定性) の 3 指標で、評価は 75 パーセンタイルです
  • 閾値は LCP 2.5 秒 / INP 200 ミリ秒 / CLS 0.1 が良好の境目、LCP 4.0 秒 / INP 500 ミリ秒 / CLS 0.25 を超えると不良です
  • INP はブラウザのメインスレッドを測る指標で、サーバー応答の遅さでは悪化しません。サーバーの遅さは LCP や TTFB に出ます
  • INP の対象はクリック・タップ・キー入力のみ。スクロールは含みません
  • CLS の主因は寸法未指定の遅延コンテンツです。届く前に場所を確保するのが対策の原則です
  • 3 指標は別々の系統に対応しているので、組み合わせを見れば疑うべき場所が絞れます
  • INP はラボデータでは測れません。CLS は計測条件を絞らないと再現しません

次に読む