累積レイアウトシフト(CLS)
累積レイアウトシフトが測るもの、インパクト×距離によるスコア、セッションウィンドウ、閾値、一般的な原因、修正とデバッグ方法を解説します。
言語
累積レイアウトシフト(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 — Cumulative Layout Shift(CLS)は、読んだりタップしたりしている間に、ページ上の見えるものが予期せずどれだけ動くかを測ります。遅れて読み込まれた画像で本文が押し下げられたり、押そうとしたボタンが跳ねて別のボタンに当たったりする動きです。0から始まるスコアで、0,1以下が良好。多くは読み込み前に領域を確保していない要素が原因です。
CLSとは
この現象は、用語を知らなくても経験したことがあるはずです。記事を読んでいると、見ている場所の上で広告や画像の読み込みが終わり、ページ全体が突然下へ跳ねることがあります。「キャンセル」をタップしようとした瞬間にバナーが現れ、代わりに「確認」を押してしまうこともあります。この予期しない動きがレイアウトシフトで、Cumulative Layout Shiftはその大きさを数値化する指標です。
CLSは3つのCore Web Vitalsの1つです。Googleが追跡するページ体験指標の組で、メインコンテンツの読み込み速度を表すLargest Contentful Paintや、タップへの応答の速さを表すInteraction to Next Paintと並びます。CLSが扱うのは、ページが静止しているかという視覚的安定性です。
スコアの仕組み(概略)
CLSは時間ではなくスコアです。CLSが0,05でも、何かが50ミリ秒続くという意味ではありません。単位のない数値で、動く画面の面積が大きいほど、また移動距離が長いほど、スコアは高く(悪く)なります。
目安はシンプルです。
- 0,1以下 — 良好。
- 0,1超から0,25以下 — 改善が必要。
- 0,25超 — 不良。
もう1つ大切な点があります。ボタンをタップしたりメニューを開いたりした直後のシフトは、あなたの操作が原因で予想できるため、ページの評価には通常入りません。数えるのは予期しない動きだけです。
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なぜ起きるのか(そして修正方法)
ほとんどのレイアウトシフトは、何かが読み込まれ、ページが確保していなかった領域を使い始めるという同じ原因に行き着きます。代表例は次のとおりです。
- サイズ指定のない画像と動画。 ブラウザーは画像が届くまで高さを把握できないため、読み込み後に下の本文が押し下げられます。
widthとheight(またはCSSのaspect-ratio)を必ず指定し、先に場所を確保します。 - 広告、埋め込み、iframe。 同じ問題なので、あらかじめ領域を予約します。
- Webフォント。 カスタムフォントがフォールバックから切り替わると、本文が再配置されることがあります。
- 後から現れる要素。 Cookieバナー、「おすすめ」ボックスなど、すでに見ているコンテンツの上へ挿入されるものです。
覚え方はこうです。後から表示されるものがあるなら、そのものに見合う穴を先に空けておく。表示されたときに、ほかの要素が動かずに済みます。
実際の式、「セッションウィンドウ」のルール、ラボとフィールドでCLSが食い違う理由、原因と修正の一覧を知りたい場合は、Advancedタブへ切り替えてください。
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-adjust、transformだけのアニメーションで対処します。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になります。
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
hadRecentInputflag 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ミリ秒の除外はタップ、クリック、キー入力のような離散的イベントだけに適用されます。スクロールやピンチズームのような連続的ジェスチャーでは適用されません。スクロール中にコンテンツが動けば、それも数えられます。この区別を誤った説明は多いので、正確に扱ってください。
閾値とスコアの出どころ
“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
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の数字が悪く見える理由を説明しきれないことがあります。
よくある原因
私が目にする頻度のおおよその順です。
- 寸法のない画像と動画。 予約された高さがないため、メディアの読み込み時に下のすべてが跳ねます。
- 領域を予約していない広告、埋め込み、iframe。 広告ネットワークは動的なサイズを配信し、埋め込みは読み込み前に高さを知らせません。
- 既存コンテンツの上へ動的に挿入されるコンテンツ。 Cookieバナー、通知バー、「関連」ウィジェット、遅れて読み込むプロモーションなど、画面上のものを押し下げる要素です。
- Webフォント(FOIT/FOUT)。 カスタムフォントとフォールバックのメトリクスが違うと、切り替え時に本文が再配置されます。
- レイアウトを発生させるプロパティのアニメーション。
top、left、margin、box-shadow、box-sizingを動かすと、ブラウザーは毎フレームページを再レイアウトします。
修正方法
原因ごとに対策を対応させます。
- 画像・動画 — 領域を予約する。
widthとheight属性を設定すれば、ブラウザーがアスペクト比を計算してボックスを確保できます。レスポンシブ対応には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 slotdivis the most effective way to do this.”(翻訳)「広告スロットのdivに高さと幅を直接固定するのが、これを行う最も効果的な方法です。」としています。複数サイズのスロットでは、設定可能な最大サイズを予約します。遅れて読み込むコンテンツは下へ置き、残ったシフトがスクロール範囲外になるようにします。 - 動的コンテンツ — フローへ挿入しない。 最終サイズに合うプレースホルダーを用意するか、挿入ではなくオーバーレイで表示します。スケルトンローダーが役立つのは、最終寸法と完全に一致する場合だけです。数ピクセル短いだけでも本物のコンテンツがシフトを起こします。予告なく挿入するより、ユーザー操作の「さらに読み込む」を優先します。
- フォント — メトリクスを合わせる。
font-display: optionalはCLSリスクを実質ゼロにできる唯一の値です。swapは見えないテキストを減らしますが、交換時にシフトすることがあります。さらに良い方法はCSSのメトリクス上書き、size-adjust、ascent-override、descent-override、line-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.”(翻訳)「これらの要素は、レイアウト不安定性の「根本原因」と間接的にしか関係しない可能性があります。」と説明しています。跳ねた本文は、上にあるサイズ未指定の画像が遅れて読み込まれたときの被害者であることが多く、症状ではなく原因を直します。シフトの開始時刻を記録し、その同じ時間帯に完了したネットワーク要求、到着した画像やフォント、リサイズ、クラスやスタイルの変更を確認する、という時刻からトリガーへのループで調べてください。属性付けされたノードは、トリガーと結び付くまでは手掛かりであって証拠ではありません。
AI要約
Advanced版の要点を短くまとめます。
- CLS = 視覚的安定性。 見えているコンテンツの予期しない動きを測るCore Web Vitalで、Largest Contentful PaintとInteraction to Next Paintに並びます。
- 単位のないスコアであり、時間ではない。 0,05は比率で、50ミリ秒ではありません。
- シフトごとの式:
impact fraction × distance fraction— ビューポートのどれだけが動いたかに、ビューポート最大寸法に対する移動距離を掛けます。 - 指標は最大のセッションウィンドウ。 シフト間は1秒以内、ウィンドウ全体は5秒以内で、生涯合計ではありません。長寿命ページやSPAを不利にしないため、2021年6月に変更され、平均ではなく最大が選ばれました。
- 閾値(フィールドデータの75パーセンタイル): 良好≤0,1、改善が必要≤0,25、不良>0,25。
- 除外: ビューポート外のシフトは対象外。離散的な入力(タップ、クリック、キー入力)から500ミリ秒以内のシフトも除外されます。スクロールは免除されません。
- 原因: 寸法のない画像・動画・広告・iframe・埋め込み、既存コンテンツの上への挿入、Webフォント、レイアウトを発生させるプロパティのアニメーション。
- 修正:
width/heightまたはaspect-ratioを設定し、動的コンテンツの領域を予約します(スケルトンは正確な寸法に合わせる)。font-displayとsize-adjustを使い、アニメーションはtransformだけにします。 - ラボ≠フィールド。 Lighthouseはページを操作せず、ライフサイクル全体も実行しないため、ほぼ0になることがあります。Googleがランキングに使うのはフィールドデータ(CrUX/PageSpeed Insights)です。iframeのシフトは、ラボツールでもRUMツールでも親スコアへ伝わらないことが多い点にも注意してください。
- ランキング: Googleがページエクスペリエンスの中でランキングシステムが使うと説明する入力の1つです。公開された重みやタイブレーカー規則はないため、特定の仕組みを追いかけず「良好」に入ることを優先します。CrUXには約28日の遅れがあり、属性付けされた要素が根本原因とは限りません。
公式ドキュメント
GoogleとChromeチームによる一次資料です。
CLSの中核資料
- Cumulative Layout Shift(CLS) — 定義、インパクト×距離の式、セッションウィンドウ、閾値、
hadRecentInputの除外を扱う公式リファレンス(Milica Mihajlija、Philip Walton)。 - Cumulative Layout Shiftを最適化する — 画像、広告・埋め込み、挿入コンテンツ、フォント、アニメーションの原因と修正を扱う公式ガイド。
- レイアウトシフトをデバッグする — Chrome DevTools、Layout Shift Regionsオーバーレイ、LayoutShiftAttribution APIでシフトを見つける方法(Katie Hempenius、Barry Pollard)。
背景と測定
- WebツールにおけるCumulative Layout Shiftの進化 — 2021年6月に指標が全シフトの合計から最大セッションウィンドウへ移った理由(Chrome Speed MetricsチームのAnnie Sullivan、Hongbo Song)。
- Core Web Vitalsの指標閾値はどう定義されたか — 0,1 / 0,25の帯を支えるユーザー調査と達成可能性のデータ。
- Web Vitalsの測定を始める — ラボとフィールドの違い、ラボCLSが人工的に低く見える理由。
- フォントのベストプラクティス —
font-display、メトリクス上書き、フォント関連CLSの先読み。
広告と検索
- レイアウトシフトを最小化する — Google Publisher Tagの広告スロット領域予約ガイド。
- Core Web VitalsとGoogle検索結果を理解する — CLSを含むCWVが検索でどう扱われるか。
出典からの引用
GoogleとChromeチームが公表した発言です。各リンクは、引用箇所へ直接移動するテキストフラグメントです。
Google — CLSとは何か
- “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指標であり、ユーザー中心の視覚的安定性の指標として、予期しないレイアウトシフトの頻度を数値化します。」 引用へ移動
- “CLS measures the largest burst of layout shift scores for every unexpected layout shift that occurs during the entire lifecycle of a page.”(翻訳)「CLSは、ページのライフサイクル全体で起きる予期しない各シフトについて、最大のスコアのまとまりを測ります。」 引用へ移動
Google — 式
- “layout shift score = impact fraction * distance fraction”(翻訳)「レイアウトシフトスコアは、インパクト分率と距離分率の積です。」 引用へ移動
- “The impact fraction measures how unstable elements impact the viewport area between two frames.”(翻訳)「インパクト分率は、2つのフレーム間で不安定な要素がビューポート領域に与える影響を測ります。」 引用へ移動
- “The distance fraction is 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).”(翻訳)「距離分率は、フレーム内で不安定な要素が移動した最大の水平または垂直距離を、ビューポートの最大寸法で割った値です。」 引用へ移動
Google — セッションウィンドウ
- “A burst of layout shifts, known as a session window, is when 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秒となるまとまりです。」 引用へ移動
Google — 閾値とユーザー入力
- “To provide a good user experience, sites should strive to have a CLS score of 0.1 or less… a good threshold to measure is the 75th percentile of page loads, segmented across mobile and desktop devices.”(翻訳)「良いユーザー体験のため、サイトはCLSを0,1以下にすることを目指すべきで、測定には端末別ページ読み込みの75パーセンタイルが適切です。」 引用へ移動
- “Layout shifts that occur within 500 milliseconds of user input will have the
hadRecentInputflag set, so they can be excluded from calculations.”(翻訳)「ユーザー入力から500ミリ秒以内のシフトにはhadRecentInputフラグが設定され、計算から除外できます。」 引用へ移動 - “Layout shifts that occur in response to user interactions (such as clicking or tapping a link, pressing a button, or typing in a search box) are generally fine, as long as the shift occurs close enough to the interaction that the relationship is clear to the user.”(翻訳)「リンクのクリックやタップ、ボタンの押下、検索欄への入力など、ユーザー操作に応じたシフトは、操作との関係が明確なほど近くに起きるなら一般に問題ありません。」 引用へ移動
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以下は気づかれるものの過度に不快ではないと評価されました。」 引用へ移動
Google — 広告スロットの領域確保
- “Setting a fixed height and width directly on the ad slot
divis the most effective way to do this.”(翻訳)「広告スロットのdivに高さと幅を直接固定するのが、これを行う最も効果的な方法です。」 引用へ移動
Google — 属性付けされた要素と根本原因
- “elements listed as sources are the elements that shifted during the layout shift. However, it’s possible that these elements are only indirectly related to the ‘root cause’ of layout instability.”(翻訳)「sourcesとして列挙された要素はシフト中に動いた要素ですが、レイアウト不安定性の「根本原因」とは間接的にしか関係しない可能性があります。」 引用へ移動
CLSの原因→修正チェックリスト
上から順に進めてください。最初の2項目で、現実のCLSの大半を直せます。
- すべての
<img>と<video>にwidth+heightがある(またはCSSのaspect-ratio)。レスポンシブレイアウトではimg { height: auto; width: 100%; }も使います。 - 広告スロット、iframe、埋め込みが領域を予約している。
min-height/aspect-ratioを使い、複数サイズの広告スロットは設定可能な最大サイズを確保します。 - 遅延読み込みのコンテンツは可能ならスクロール範囲外に置く。 残ったシフトが評価対象になりません。
- 挿入コンテンツ(Cookieバナー、プロモーション、「関連」ウィジェット)はオーバーレイするか、先に領域を確保する。 既存コンテンツの上へ挿入しません。
- スケルトンプレースホルダーは最終コンテンツの寸法と完全に一致している。 数ピクセルの違いでもシフトします。
- Webフォントは許容できる場合
font-display: optionalを使い、そうでなければswapとsize-adjust/ascent-overrideでフォールバックのメトリクスを合わせる。 重要なフォントは先読みします。 - アニメーションは
transformだけを使う。top、left、margin、box-shadow、box-sizingは使いません。 - スコアをラボだけでなくフィールドデータで確認している。 PageSpeed Insights、Search Console、CrUXを使います。
- ページを初回読み込みするだけでなく、操作してシフトを再現している。 スクロール、メニュー展開、遅延読み込みの発火まで試します。
- 広告・iframeのシフトをフィールドで確認している。 ラボツールでは親スコアへ伝播しないことがあります。
CLSチートシート
数値
| 区分 | CLS(フィールドの75パーセンタイル) |
|---|---|
| 良好 | ≤ 0,1 |
| 改善が必要 | > 0,1〜0,25 |
| 不良 | > 0,25 |
一行での定義
layout shift score = impact fraction × distance fraction(シフトごと)。- CLS = シフトの最大のセッションウィンドウ — シフト間は1秒以内、ウィンドウ全体は5秒以内。生涯合計ではありません(2021年6月以前の定義)。
- 単位のないスコアであり、時間ではありません。
除外されるもの
- ビューポート外(現在見えていない場所)のシフト。
- 離散的な入力(タップ、クリック、キー入力)から500ミリ秒以内のシフト —
hadRecentInput。 - 除外されないもの: スクロールやピンチ(連続ジェスチャー)中のシフト。
原因→修正
| 原因 | 修正 |
|---|---|
| 寸法のない画像・動画 | width+height属性、またはCSSのaspect-ratio |
| 広告・iframe・埋め込み | 領域を予約:min-height/aspect-ratio、広告スロットのdivを固定サイズにする |
| ビューポート上部への挿入コンテンツ | オーバーレイまたは先行予約。ユーザー操作で発火させる |
| Webフォント(FOIT/FOUT) | font-display: optional/swap+size-adjustのメトリクス上書き。先読みする |
| レイアウトを発生させるアニメーション | top/left/marginではなくtransformで動かす |
測定時の落とし穴
- Lighthouse(ラボ)は~0になることが多い。 ページを操作せず、ライフサイクル全体も実行しないためです。Googleがランキングに使うのは、フィールドのCrUX / PageSpeed Insightsです。
- CrUXには約28日の遅れがある。 修正が反映されるまで数週間かかります。
- iframeのシフトは、ラボツールでは親スコアへ伝わらないことが多いです。
- 属性付けされた要素は動いた要素であり、根本原因とは限りません。
CLSを測定・デバッグするツール
フィールドデータ(Googleがランキングに使うもの)
- PageSpeed Insights — ページとオリジンのCrUXフィールドCLSに、Lighthouseのラボ実行を並べて表示します。ラボとフィールドの差を確認する最短の方法です。
- Search Console — Core Web Vitalsレポート — サイト全体のURLグループごとのフィールドCLSを、ステータス別にまとめます。
- CrUX(Chrome User Experience Report)— 基礎となるフィールドデータセットです。CrUXダッシュボードやBigQueryで履歴を調べられます。
ラボデータ(デバッグ用)
- Chrome DevTools — Performanceパネル — トレースを記録してLayout Shiftsトラックを読みます。シフトをクリックすると動いた要素が強調され、シフトスコアも表示されます。Live Metricsでは操作中のCLS更新をリアルタイムで確認できます。
- Layout Shift Regionsオーバーレイ — DevTools → Settings → More tools → Rendering → Layout Shift Regions。再読み込みすると、動いた領域が点滅して見えるようになります。
- Lighthouse — ラボCLSを手早く確認できますが、初期読み込みのシフトしか捕捉しません。
- WebPageTest — フィルムストリップとトレース付きのラボCLSです。
RUM(自前のフィールドデータ)
- web-vitals JavaScriptライブラリ —
onCLS()で自分の訪問者の実ユーザーCLSを報告します(約2 KB)。実際の体験を最も正確に把握できます。 - PerformanceObserver(
layout-shift) — ライブラリがラップする生のAPIで、どの要素が動いたかを示すLayoutShiftAttributionのsourcesも取得できます。
ツール自体がどうスコアを測るか
このページで説明した指標の実例です。知名度のあるページ速度・監視サービスを、実ユーザーのモバイルCLS(Chrome UX Reportのフィールドデータ)で順位付けしています。
最初にどのCLS修正を行うべきか
What is causing the visible layout shift?
本当の問題を隠すCLSの失敗
Lighthouseがきれいなら証明になると考える
Lighthouseは、同意バナー、広告、または操作をきっかけに起きるシフトが発生する前に終了することがあります。ラボ実行はデバッグに使い、問題を直したと判断する前にCrUXまたは自前の実ユーザーモニタリングも確認してください。
DevToolsが示した要素だけを直す
動いた要素は被害者であることが多く、その上で遅れて読み込まれた要素が原因かもしれません。トレースを再生し、動く直前に何が挿入されたか、またはサイズ変更されたかを確認してください。
推測した固定高さで領域を予約する
固定プレースホルダーは、レスポンシブなコンテンツが想定より高くても低くても、2回目のシフトを起こすことがあります。コンテンツの比率が分かっている場合は、固有の寸法またはaspect-ratioを使ってください。
レイアウトプロパティをアニメーションさせる
top、left、またはマージンを変更すると、周囲のコンテンツまで動くことがあります。文書フローを変える必要がない効果なら、transformでアニメーションさせます。
症状からCLS問題を診断する
フィールドCLSは悪いのにラボスコアはほぼ0
考えられる原因: 操作後、長いセッション中、または一部のユーザーだけでシフトが起きています。修正: Performanceパネルを記録しながら実際の導線を再現し、実ユーザーモニタリングにweb-vitalsの属性付けを追加します。確認: 問題の操作と動いた要素がトレースまたはRUMの記録に現れることを確認します。
カスタムフォントが到着すると本文が跳ねる
考えられる原因: フォールバックとWebフォントのメトリクスが異なります。修正: 必要な場合だけ重要なフォントを先読みし、フォントのメトリクス上書きでフォールバックを合わせます。確認: キャッシュを無効にして再生し、交換時のシフトがLayout Shiftsトラックに記録されなくなったことを確認します。
バナーや広告がページを押し下げる
考えられる原因: コンテンツが到着する前の寸法をスロットが予約していません。修正: 安定したコンテナを割り当てるか、見えているコンテンツを押し出さない位置にメッセージを置きます。確認: 読み込みをスロットリングし、スロットが同じ領域を維持することを確認します。
テストではCLSが改善するのにPageSpeed Insightsでは改善しない
考えられる原因: CrUXは即時のデプロイ確認ではなく、移動するフィールドデータセットです。修正: まずラボとRUMで変更を確認し、その後フィールドのウィンドウが入れ替わるのを待ちます。確認: 公開CrUXの集計が追随する前に、リリース後の自分のフィールド分布が改善することを確認します。
ブラウザーでレイアウトシフトを記録する
問題を再現する前に、DevToolsのConsoleへ貼り付けます。最近のユーザー入力に結び付いたシフトは無視し、スコアとブラウザーが属性付けした要素を出力します。
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.hadRecentInput) continue;
console.table({
value: entry.value,
time: Math.round(entry.startTime),
elements: entry.sources?.map((source) => source.node),
});
}
});
observer.observe({ type: 'layout-shift', buffered: true });属性付けされたノードは手掛かりであって、原因の証明ではありません。同じトレース内で、タイムスタンプをネットワーク要求、フォント読み込み、DOM挿入と照合してください。
CLSの修正を検証する
予約領域テスト
実行するテスト: キャッシュを無効にし、接続をスロットルして再読み込みし、PerformanceパネルのLayout Shiftsトラックを記録します。期待結果: メディアや埋め込みが読み込まれる前後で同じ領域を保ちます。失敗の解釈: コンテナの寸法が遅れて到着するコンテンツに依存しています。監視期間: トレース中に直ちに確認します。ロールバック条件: 新しいプレースホルダーがクリッピング、過剰な空白、またはレスポンシブ境界で新たなシフトを作ることです。
フォント交換テスト
実行するテスト: テキストとLayout Shiftsトラックを見ながら、キャッシュを無効にして再読み込みします。期待結果: フォールバックからWebフォントへの切り替えで、測定可能なシフトが起きません。失敗の解釈: フォールバックのメトリクスがまだ異なるか、重要なフォントの到着が遅すぎます。監視期間: ラボを繰り返し実行する間、直ちに確認します。ロールバック条件: 変更によってテキストが長く隠れたり、最終的なタイポグラフィが大きく不自然になったりすることです。
フィールドでの確認
実行するテスト: 変更したテンプレートのリリース後onCLS()データをリリース前の基準値と比較し、その後CrUXを観測します。期待結果: 実ユーザーのp75が改善し、重要な導線の悪化した裾野がありません。失敗の解釈: 別の遅延または操作起点の発生源が残っています。監視期間: トラフィックの到着に合わせてRUMを確認し、CrUXは28日間の移動ウィンドウで確認します。ロールバック条件: リリース後にCLSまたはユーザー操作エラーが一貫して悪化することです。
追跡する価値があるCLS指標
p75の実ユーザーCLS
指標: 重要な各テンプレートと端末区分におけるCLSの75パーセンタイル。分かること: 大半の訪問が視覚的安定性の目標を満たすかどうか。取得方法: CrUX、PageSpeed Insights、またはweb-vitalsのRUM。基準・現実的な範囲: 0,1以下が良好、0,1–0,25は改善が必要、0,25超は不良。頻度: RUMでリリースを監視し、フィールドの移動傾向を毎月確認します。
不良訪問率
指標: CLSが0,25を超えた実訪問の割合。分かること: p75が許容範囲でも、深刻な裾野を隠していないか。取得方法: onCLS()イベントをテンプレートと導線別に区分します。基準・現実的な範囲: サイトの基準値を作り、不良区分を下げます。トラフィック構成によって普遍的な目標は誤解を招きます。頻度: トラフィックの多いテンプレートでは毎週、レイアウトのリリース後にも確認します。
原因別のシフト属性付け
指標: 要素またはコンポーネント別にまとめたlayout-shiftエントリ。分かること: 繰り返し現れる実装のうち、どれが不安定性を最も多く所有しているか。取得方法: web-vitalsの属性付けビルドまたはPerformanceObserver。基準・現実的な範囲: 共通の範囲はないため、総影響量と影響を受けた訪問数でコンポーネント同士を比較します。頻度: テンプレートまたはコンポーネントをリリースするたびに確認します。
時間を使う価値のあるリソース
公式・詳しい資料
- Cumulative Layout Shift(CLS) — 公式リファレンス。
- Cumulative Layout Shiftを最適化する — 公式の修正ガイド。
- レイアウトシフトをデバッグする — DevToolsの手順。
- WebツールにおけるCumulative Layout Shiftの進化 — 2021年6月のセッションウィンドウ変更を、変更を実施したチームが説明します。
実務家による資料
- Cumulative Layout Shift(CLS)の問題を修正する方法 — Smashing MagazineのBarry Pollard。フォント記述子と、「動いた要素が根本原因とは限らない」問題を詳しく扱います。
- 実務でのCumulative Layout Shift — CloudflareおよびW3C Web Performance WGのNic Jansma。iframeの属性付けの空白、5要素の属性付けサンプル、ツール間の差異など、測定上の細部を最もよく説明しています。
- Cumulative Layout Shiftを測定・最適化する — DebugBear。
- ほぼ完全なガイド:Cumulative Layout Shift — Jess Peck。SPAナビゲーションのシフトや連続ジェスチャーの除外の細部まで扱います。
- レイアウトシフトの原因 — CLS culpritインサイトパネルのChrome DevToolsドキュメント。web.devのデバッグガイドの補助資料です。
- Cumulative Layout Shift(CLS)を修正する方法 — Kinsta。ギャラリー画像、遅延ウィジェット、Cookieバナーなど、WordPress固有の原因を扱うCMS向けの実践ガイドです。
- Layout Instability API — WICG仕様。CLSの基盤となるブラウザーAPIで、自前RUMや正確な
hadRecentInputの意味を確認するときに役立ちます。
自分の仕事での位置づけ
- CLSはCore Web Vitalsについて扱う記事全体で、まず満たすべき基準の指標です。追跡し、良好帯へ入れ、LCP、INP、コンテンツとのバランスを保ちます。GoogleはCLSの具体的な重みやタイブレーカー規則を公開していないため、監視する入力の1つではありますが、すべてではありません。
引用する価値のある統計
- 0,1の閾値は知覚研究に基づく。 Googleのユーザー調査では、0,15以上のシフトは一貫して妨害的と受け取られ、0,1以下は気づかれるものの過度に不快ではないとされました。 出典
- CLSは最も合格しやすいCore Web Vital。 私の企業監査では、大多数のサイト(しばしば80%以上)がCLSの基準を満たす一方、3指標すべてに合格するのは半数を少し超える程度です。CLSが足を引っ張ることはまれです。
- 2021年6月の変更は悪化させず、改善した。 CLSが最大セッションウィンドウへ移ったとき、悪いスコアになったオリジンはなく、多くは変わらず、無限スクロールや遅いUIの一部は改善しました。 出典
- 寸法のないメディアはいまだに多い。 Web Almanacの業界クローリングでは、明示的な寸法のない画像を配信するページが一貫して多く見つかります。最も一般的で、直しやすいCLS原因です。
- 世界のWebサイトの72%が、現在は良好なCLSを達成している。 (2025年のWeb Almanac / HTTP Archiveデータ)CLSは最も合格しやすいCore Web Vitalですが、モバイルページの62%には明示的な寸法のない画像が少なくとも1つ残っており、最も一般的な原因です。 出典:HTTP Archive / Web Almanac
- 事業への影響: Rakuten 24は、CLSが高いユーザーと比べて低いユーザーの訪問者1人あたり収益が53,37%増加したと報告しています。よく引用される事例ですが、特定のCLS数値が他サイトの特定の事業成果を引き起こす証拠ではありません。 出典:corewebvitals.ioの事例
動画
- Google検索セントラル / Chrome for Developers(YouTube)— Layout ShiftsトラックやLayout Shift RegionsオーバーレイのDevToolsデモを含む、Core Web Vitalsと「レイアウトシフトをデバッグする」解説です。 チャンネル
Cumulative Layout Shiftを試す
視覚的な不安定性の測定と修正について、5問の簡単な問題です。それぞれ答えを選んでから確認してください。
変更履歴
2026年8月11日に更新。
編集概要と記録された変更の詳細。変更の詳細
-
変更の詳細な注記は現在英語でのみ提供されています。
-
変更の詳細な注記は現在英語でのみ提供されています。
完全な比較は利用できません — この改訂の以前のスナップショットがアーカイブされていません。
2026年7月17日に更新。
編集概要と記録された変更の詳細。変更の詳細
-
変更の詳細な注記は現在英語でのみ提供されています。
-
変更の詳細な注記は現在英語でのみ提供されています。
-
変更の詳細な注記は現在英語でのみ提供されています。
完全な比較は利用できません — この改訂の以前のスナップショットがアーカイブされていません。