累積レイアウトシフト(CLS)

累積レイアウトシフトが測るもの、インパクト×距離によるスコア、セッションウィンドウ、閾値、一般的な原因、修正とデバッグ方法を解説します。

初回公開:2026年6月26日 · 最終更新:2026年8月11日 · Advanced
言語

累積レイアウトシフト(CLS)は、ページを利用している間に見えるコンテンツが予期せずどれだけ動くかを測るCore Web Vitalです。単位のないスコアで、各シフトのインパクト分率×距離分率から計算され、2021年6月以降は生涯合計ではなく最大セッションウィンドウが使われます。フィールドデータの75パーセンタイルで、0,1以下が良好、0,1超から0,25以下は改善が必要、0,25超は不良です。サイズのない画像、広告、iframe、埋め込み、Webフォント、上部への挿入が主な原因で、領域予約、font-display、メトリクス調整、transformで修正します。Lighthouseが低くても、Googleが実際に使うCrUXのフィールドデータで確認します。

TL;DR — CLSは視覚的安定性を測るCore Web Vitalです。各シフトはimpact fraction × distance fractionでスコア化され、指標にはシフトの最大セッションウィンドウ(シフト間は1秒以内、ウィンドウ全体は5秒以内)が使われます。2021年6月以前のような生涯合計ではありません。フィールドデータの75パーセンタイルで、0,1以下が良好、0,25以下は改善が必要、0,25超は不良です。ビューポートに見えているシフトだけが対象で、離散的な入力から500ミリ秒以内のシフトは除外されます(スクロールは除外されません)。主な原因はサイズのない画像・動画・広告・iframe・埋め込み、Webフォント、既存コンテンツの上への挿入で、領域予約、font-display/size-adjusttransformだけのアニメーションで対処します。Lighthouse(ラボ)がほぼ0を返しても、ページ全体のライフサイクルを操作しないためです。Googleが実際に見るのはフィールドデータ(CrUX)です。

CLSが測るもの

Googleの定義では、“Cumulative Layout Shift (CLS) is a stable Core Web Vital metric. It’s an important, user-centric metric for measuring visual stability because it helps quantify how often users experience unexpected layout shifts.”(翻訳)「Cumulative Layout Shift(CLS)は安定したCore Web Vital指標であり、ユーザー中心の視覚的安定性の指標として、予期しないレイアウトシフトをユーザーがどの程度経験するかを数値化するものです。」 ここで重要なのはunexpected(予期しない)という語です。ユーザーの操作ではなく、コンテンツが自力で動くことを指します。

CLSはCore Web Vitalsの組で、Largest Contentful Paint(読み込み)とInteraction to Next Paint(応答性)に並びます。LCPとINPはミリ秒で測りますが、CLSは異質な単位のない比率スコアです。CLSの0,05は50ミリ秒ではなく、時間の単位を持ちません。

式:インパクト×距離

シフトごとの計算式をGoogleは次のように定義しています。

layout shift score = impact fraction × distance fraction
  • インパクト分率は、“measures how unstable elements impact the viewport area between two frames”(翻訳)「2つのフレームの間で、不安定な要素がビューポート領域にどのような影響を与えるかを測ります。」— 移動する要素が移動前後に占めた、ビューポートに対する合算の可視領域です。
  • 距離分率は、“the greatest horizontal or vertical distance any unstable element has moved in the frame divided by the viewport’s largest dimension (width or height, whichever is greater).”(翻訳)「フレーム内で不安定な要素が移動した最大の水平または垂直距離を、ビューポートの最大寸法(幅と高さの大きい方)で割った値です。」です。

2つの値は別々に効きます。画面の大部分を横切る小さな要素と、わずかに動く大きな要素では、スコアが大きく異なることがあります。web.devの例では、インパクト分率0.75と距離分率0.25を掛けると、レイアウトシフトスコアは0.1875になります。

One shift scores the visible area affected multiplied by the farthest movement relative to the viewport. 出典: web.dev

Three cards form the equation. Impact fraction is 0.75: the visible viewport area affected between two frames. Distance fraction is 0.25: the farthest movement divided by the viewport's largest dimension. Multiplying them produces a unitless individual layout-shift score of 0.1875. CLS ultimately keeps the largest session-window total, not a lifetime sum of every shift.

© Patrick Stox LLC · CC BY 4.0 ·

セッションウィンドウ:最も誤解されやすい部分

CLSについて最も頻繁に誤って説明され、かつ最も覚えてほしい事実があります。**CLSはページの生涯にわたる全シフトの合計ではありません。**以前はそうでしたが、2021年6月に変更されました。

現在の定義は、“CLS measures the largest burst of layout shift scores for every unexpected layout shift that occurs during the entire lifecycle of a page.”(翻訳)「CLSは、ページのライフサイクル全体で起きる予期しない各レイアウトシフトについて、スコアの最大のまとまりを測ります。」 そのまとまり、つまりセッションウィンドウは、“one or more individual layout shifts occur in rapid succession with less than 1-second in between each shift and a maximum of 5 seconds for the total window duration.”(翻訳)「1回以上のレイアウトシフトが短い間隔で連続し、各シフト間は1秒未満、ウィンドウ全体は最大5秒となる状態です。」です。CLSはこのウィンドウの最大値であり、合計でも平均でもありません。

Evidence for this claim CLS uses the largest session window of unexpected layout shifts, with gaps under one second and a maximum five-second window; recent discrete input can exclude a shift. Scope: Current CLS session-window and recent-input rules. Confidence: high · Verified: web.dev: Cumulative Layout Shift

なぜ変わったのでしょうか。以前の「すべてを合計する」定義は、長く動き続けるページをひそかに不利にしていました。シングルページアプリや無限スクロールのフィードは、個々のシフトが小さく間隔を空けていても、存在時間が長いだけでCLSが積み上がりました。Chrome Speed Metricsチームは、滞在時間を罰しないよう最大セッションウィンドウへ移行し、平均ではなく最大を選びました。小さな二次的シフトを直した結果スコアが悪化するという逆転現象を避けるためです。変更時には、悪化したオリジンはなく、多くは変化せず、一部の遅いUIや無限スクロールのページは改善しました。「すべてのシフトの合計」と書かれた古い記事は、もう更新されていません。

何が数えられ、何が数えられないか

実際にスコアへ入るかどうかを決める除外条件は3つあります。

  • スクロールせずに見えない場所は対象外。 現在のビューポートに見えているコンテンツのシフトだけが採点されます。長いページの下部で、ユーザーが一度もスクロールしない場所のシフトは影響しません。実務上は、ページ下部を追いかけるより、ビューポート内のシフトを直す方がほぼ常に投資効果が高くなります。
  • ユーザー起点のシフトには500ミリ秒の猶予がある。 “Layout shifts that occur within 500 milliseconds of user input will have the hadRecentInput flag set, so they can be excluded from calculations.”(翻訳)「ユーザー入力から500ミリ秒以内に起きたレイアウトシフトにはhadRecentInputフラグが設定され、計算から除外できます。」Googleの見解では、“that occur in response to user interactions… are generally fine, as long as the shift occurs close enough to the interaction that the relationship is clear to the user.”(翻訳)「ユーザー操作に応じて起きるシフトは、操作との関係が明確になるほど近いタイミングなら、一般に問題ありません。」アコーディオンを開く、メニューを展開する、といった動きは予想できるため許容されます。
  • スクロールは無条件の免除ではない。 500ミリ秒の除外はタップ、クリック、キー入力のような離散的イベントだけに適用されます。スクロールやピンチズームのような連続的ジェスチャーでは適用されません。スクロール中にコンテンツが動けば、それも数えられます。この区別を誤った説明は多いので、正確に扱ってください。
Evidence for this claim A layout shift occurring within 500 milliseconds of a qualifying recent user input has hadRecentInput set and is excluded from CLS. Scope: field and lab Confidence: high · Verified: Cumulative Layout Shift (CLS)

閾値とスコアの出どころ

“To provide a good user experience, sites should strive to have a CLS score of 0.1 or less,“(翻訳)「良いユーザー体験のため、サイトはCLSを0,1以下にすることを目指すべきです。」これは*“the 75th percentile of page loads, segmented across mobile and desktop devices.”*(翻訳)「モバイルとデスクトップの端末別に分けた、ページ読み込みの75パーセンタイル」で測ります。全体の区分は次のとおりです。

Evidence for this claim CLS is good at 0.1 or less and poor above 0.25, assessed at the 75th percentile of page loads. Scope: Current web.dev CLS field thresholds. Confidence: high · Verified: web.dev: Cumulative Layout Shift
  • 良好: ≤ 0,1
  • 改善が必要: 0,1 – 0,25
  • 不良: > 0,25
Evidence for this claim CLS is good at 0.1 or less and poor above 0.25, assessed at the 75th percentile of page loads. Scope: Current web.dev CLS field thresholds. Confidence: high · Verified: web.dev: Cumulative Layout Shift

0,1という線は恣意的なものではありません。Googleのユーザー調査では、“levels of shift from 0.15 and higher were consistently perceived as disruptive, while shifts of 0.1 and lower were noticeable but not excessively disruptive.”(翻訳)「0,15以上のシフトは一貫して妨害的だと受け取られ、0,1以下のシフトは気づかれるものの、過度に不快ではないと評価されました。」それでもっと厳しい値ではなく0,1を採用した理由の一部は、広告やソーシャル機能など第三者の埋め込みが現実のWebで頻繁にシフトを起こし、厳しすぎる基準は実用的でないためです。

「フィールドデータの75パーセンタイル」が重要なのは、最大の測定上の落とし穴につながるからです。

ラボとフィールド:数字が食い違う理由

ここで多くの人がつまずきます。LighthouseなどのラボツールはCLSを0,0近くと報告するのに、フィールドデータとGoogleでははるかに悪いことがあります。どちらかが嘘をついているのではなく、測定範囲が違うのです。ラボ実行は短い、スクリプト化された1回のページ読み込みで、スクロールせず、クリックせず、滞在もしないため、初期読み込みのシフトしか捕捉しません。フィールドデータ(CrUX)は多くのユーザー、端末、ナビゲーションによる実訪問を移動ウィンドウで集計し、CLSはページのライフサイクル全体(メニューの展開、スクロール中の遅延コンテンツ、遅れて埋まる広告など、セッションが続く限り)で定義されます。短いラボ実行では、構造上その大半を見られません。

実務上のルールは、ラボデータで特定のシフトをデバッグし、フィールドデータで本当のスコアを知ることです。GoogleはChrome User Experience Report(CrUX)のフィールドデータを、PageSpeed InsightsとSearch Consoleに表示してランキングに使います。Lighthouseが0,0でもPageSpeed Insightsが0,18なら、実際のユーザーを反映するのはフィールド側の数字だと考え、現実の訪問者と同じ操作をラボで再現してください。さらに2つ、範囲の違いがあります。Lighthouseを含む多くのツールは、CrUXが反映できる場合でもiframeのレイアウトシフトを親ドキュメントのスコアへ伝播させません。Layout Instability APIを使うRUMも同じiframeの盲点を持つため、自前の実ユーザーモニタリングでは、ファーストパーティの属性付けよりCrUXの数字が悪く見える理由を説明しきれないことがあります。

よくある原因

私が目にする頻度のおおよその順です。

  1. 寸法のない画像と動画。 予約された高さがないため、メディアの読み込み時に下のすべてが跳ねます。
  2. 領域を予約していない広告、埋め込み、iframe。 広告ネットワークは動的なサイズを配信し、埋め込みは読み込み前に高さを知らせません。
  3. 既存コンテンツの上へ動的に挿入されるコンテンツ。 Cookieバナー、通知バー、「関連」ウィジェット、遅れて読み込むプロモーションなど、画面上のものを押し下げる要素です。
  4. Webフォント(FOIT/FOUT)。 カスタムフォントとフォールバックのメトリクスが違うと、切り替え時に本文が再配置されます。
  5. レイアウトを発生させるプロパティのアニメーション。 topleftmarginbox-shadowbox-sizingを動かすと、ブラウザーは毎フレームページを再レイアウトします。

修正方法

原因ごとに対策を対応させます。

  • 画像・動画 — 領域を予約する。 widthheight属性を設定すれば、ブラウザーがアスペクト比を計算してボックスを確保できます。レスポンシブ対応にはimg { height: auto; width: 100%; }を組み合わせるか、CSSのaspect-ratioプロパティを使います。多くのサイトでは、これがCLSを最も大きく改善できる対策です。
  • 広告・埋め込み・iframe — こちらも領域を予約する。 コンテナにmin-heightまたはaspect-ratioを設定します。広告スロットについてGoogle Publisher Tagの指針は明快で、“Setting a fixed height and width directly on the ad slot div is the most effective way to do this.”(翻訳)「広告スロットのdivに高さと幅を直接固定するのが、これを行う最も効果的な方法です。」としています。複数サイズのスロットでは、設定可能な最大サイズを予約します。遅れて読み込むコンテンツは下へ置き、残ったシフトがスクロール範囲外になるようにします。
  • 動的コンテンツ — フローへ挿入しない。 最終サイズに合うプレースホルダーを用意するか、挿入ではなくオーバーレイで表示します。スケルトンローダーが役立つのは、最終寸法と完全に一致する場合だけです。数ピクセル短いだけでも本物のコンテンツがシフトを起こします。予告なく挿入するより、ユーザー操作の「さらに読み込む」を優先します。
  • フォント — メトリクスを合わせる。 font-display: optionalはCLSリスクを実質ゼロにできる唯一の値です。swapは見えないテキストを減らしますが、交換時にシフトすることがあります。さらに良い方法はCSSのメトリクス上書き、size-adjustascent-overridedescent-overrideline-gap-overrideを使い、フォールバックの寸法をWebフォントに合わせることです。重要なフォントは先読みします。
  • アニメーション — transformだけ。 top/left/marginではなく、transform(translate、scale、rotate)で動かします。transformベースのアニメーションは合成され、レイアウトを発生させないため、周囲をシフトさせません。

CLSをランキングでどう捉えるか(過大評価しない)

CLSはGoogleのページエクスペリエンスシグナルの1要素です。GoogleはCore Web Vitalsをランキングシステムが使うものだと説明していますが、現在のSearchの資料は、CLSの具体的な重み、タイブレーカーの規則、ランキング保証を公開していません。したがって「タイブレーカーだ」といった仕組みを文書化された事実として扱わず、実務上の近似と考えてください。Core Web Vitalsについて私が一貫して勧めるのは、「良好」帯に入ったら次へ進むことです。0,08を0,02へ削る作業だけで、意味のあるランキングや事業上の伸びが得られるサイトは多くありません。単一のスコアだけで収益やコンバージョンの結果を説明できることもまれです。CLSは最低限クリアすべき基準であり、LCP、INP、そして実際のコンテンツを犠牲にしてSEO施策の中心にするものではありません。

混乱を大きく減らせる運用上の注意が2つあります。

  • CrUXには約28日の遅れがある。 28日間の移動ウィンドウなので、今日リリースした修正がPageSpeed InsightsやSearch Consoleに完全に反映されるまで数週間かかります。翌朝に数字が動かなくても慌てないでください。
  • 属性付けされた要素が根本原因とは限らない。 Layout Shift Attribution APIはどの要素が動いたかを示しますが、web.devも、“it’s possible that these elements are only indirectly related to the ‘root cause’ of layout instability.”(翻訳)「これらの要素は、レイアウト不安定性の「根本原因」と間接的にしか関係しない可能性があります。」と説明しています。跳ねた本文は、上にあるサイズ未指定の画像が遅れて読み込まれたときの被害者であることが多く、症状ではなく原因を直します。シフトの開始時刻を記録し、その同じ時間帯に完了したネットワーク要求、到着した画像やフォント、リサイズ、クラスやスタイルの変更を確認する、という時刻からトリガーへのループで調べてください。属性付けされたノードは、トリガーと結び付くまでは手掛かりであって証拠ではありません。

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.