対応ブラウザ
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
予期しないレイアウト シフトは、テキストが突然動くと読み上げ中にその場所がわからなくなったり、間違ったリンクやボタンをクリックしてしまうなど、さまざまな形でユーザー エクスペリエンスに悪影響を及ぼします。場合によっては、これが深刻な被害を受けることもあります。
<ph type="x-smartling-placeholder">ページ コンテンツの予期しない移動は、通常、リソースが非同期で読み込まれる場合や、既存のコンテンツの前に DOM 要素が動的にページに追加された場合に発生します。レイアウト シフトの原因としては、サイズが不明の画像や動画、レンダリング時に元の代替サイズよりも大きいまたは小さいフォント、動的にサイズ変更されるサードパーティの広告やウィジェットなどがあります。
開発中のサイトの機能とユーザー エクスペリエンスの違いが、この問題を悪化させています。例:
- パーソナライズされたコンテンツやサードパーティ コンテンツは、多くの場合、開発と本番環境で異なる動作をします。
- 多くの場合、テスト画像はすでにデベロッパーのブラウザ キャッシュに保存されていますが、エンドユーザーにとっての読み込みに時間がかかります。
- ローカルで実行される API 呼び出しは多くの場合、非常に速いため、開発で気づかない遅延が本番環境ではかなり大きくなることがあります。
Cumulative Layout Shift(CLS)指標は、実際のユーザーで発生する頻度を測定することで、この問題に対処するのに役立ちます。
CLS とは
CLS は、ページのライフサイクル全体で発生する予期しないレイアウト シフトごとに、レイアウト シフトのスコアの最大バーストを測定します。
「レイアウト シフト」は、可視要素の位置がレンダリングされるフレームから次のフレームに変わるたびに発生します。(個々のレイアウト シフト スコアの計算方法については、このガイドの後半で説明します)。
レイアウト シフトのバースト(セッション ウィンドウ)とは、1 つ以上の個別のレイアウト シフトが連続して発生することです。各シフトの間隔は 1 秒未満で、合計ウィンドウ時間は最大 5 秒です。
最大のバーストは、そのウィンドウ内のレイアウト シフトの最大累積スコアを持つセッション ウィンドウです。
<ph type="x-smartling-placeholder"> <ph type="x-smartling-placeholder">優れた CLS スコアとは
優れたユーザー エクスペリエンスを提供するには、CLS スコアを 0.1 以下にする必要があります。ほとんどのユーザーに対してこの目標値を確実に達成するには、モバイル デバイスとデスクトップ デバイスで分けたページ読み込みの 75 パーセンタイルをしきい値として測定することをおすすめします。
<ph type="x-smartling-placeholder">この推奨事項の背景にある調査と手法について詳しくは、Core Web Vitals 指標のしきい値の定義をご覧ください。
レイアウト シフトの詳細
レイアウト シフトは、Layout Instability API によって定義されます。ビューポート内に表示される要素の開始位置(たとえば、デフォルトの書き込みモードの最上位置と左位置)が 2 つのフレーム間で変更されるたびに、layout-shift
エントリを報告します。このような要素は、不安定な要素とみなされます。
レイアウト シフトは、既存の要素の開始位置が変更された場合にのみ発生します。新しい要素が DOM に追加された場合や、既存の要素のサイズが変更された場合、その変更によって他の可視要素の開始位置が変更されない限り、レイアウト シフトとしてカウントされません。
レイアウト シフトのスコア
「レイアウト シフトのスコア」を算出するために、ブラウザはビューポートのサイズと、レンダリングされた 2 つのフレーム間のビューポート内の「不安定な要素」の移動を確認します。レイアウト シフト スコアは、その動きを計測する 2 つの尺度です。影響割合と距離割合(どちらも以下で定義)です。
layout shift score = impact fraction * distance fraction
影響分率
影響率は、不安定な要素が 2 つのフレーム間のビューポート領域に及ぼす影響を測定します。
特定のフレームの影響割合は、そのフレームと前のフレームの不安定な要素すべての表示領域の合計を、ビューポートの合計領域に対する割合として求めます。
<ph type="x-smartling-placeholder">上の画像では、1 つのフレームでビューポートの半分を占める要素があります。次のフレームで、要素がビューポートの高さの 25% 下に移動します。赤い点線の長方形は、両方のフレームでの要素の可視領域の合計を示しています。この例では、ビューポート全体の 75% であるため、影響度は 0.75
になります。
距離の割合
レイアウト シフトのスコア式のもう 1 つの部分は、不安定な要素が移動した際のビューポートからの相対距離を測定します。距離の割合は、フレーム内で不安定な要素が移動した水平方向または垂直方向の最大距離を、ビューポートの最大寸法(幅または高さのいずれか大きい方)で割ったものです。
<ph type="x-smartling-placeholder">前の例では、ビューポートの最大寸法は高さで、不安定な要素がビューポートの高さの 25% 移動したため、距離の割合は 0.25 になっています。
この例では、影響度は 0.75
、距離比は 0.25
であるため、レイアウト シフトのスコアは 0.75 * 0.25 = 0.1875
になります。
例
次の例は、既存の要素にコンテンツを追加するとレイアウト シフトのスコアにどのように影響するかを示しています。
<ph type="x-smartling-placeholder">この例では、グレーのボックスのサイズは変化しますが、開始位置は変わらないため、不安定な要素ではありません。
「Click Me!」ボタンは以前は DOM に存在していなかったので、開始位置も変わりません。
緑色のボックスの開始位置は変わりますが、部分的にビューポートの外に移動しているため、影響度数の計算時に非表示領域は考慮されません。両方のフレームの緑色のボックスの表示領域の合計(赤い点線の長方形で示されています)は、最初のフレームの緑色のボックスの面積と同じで、ビューポートの 50% になります。影響割合は 0.5
です。
紫色の矢印は、距離の割合を示しています。緑色のボックスはビューポートの約 14% 下に移動したため、距離の割合は 0.14
になります。
レイアウト シフトのスコアは 0.5 x 0.14 = 0.07
です。
次の例は、複数の不安定な要素がページのレイアウト シフトのスコアにどのように影響するかを示しています。
<ph type="x-smartling-placeholder">上の画像の最初のフレームには、動物の API リクエストの 4 つの結果がアルファベット順で並べ替えられています。2 番目のフレームでは、並べ替えられたリストにさらに結果が追加されます。
リストの最初の項目(「Cat」)は、フレーム間で開始位置を変更しないため、安定しています。同様に、リストに追加された新しいアイテムは、以前は DOM に存在していなかったので、開始位置も変わりません。しかし、「犬」、「馬」、「シマウマ」というラベルの付いたアイテムはすべて開始位置がシフトするため、要素が不安定になります。
赤色の点線の長方形は、これら 3 つの不安定な要素の結合を表します。領域の前後の領域。この例では、ビューポートの領域の約 60%(0.60
の影響割合)を占めています。
矢印は、不安定な要素が開始位置から移動した距離を表します。「ゼブラ」要素は、ビューポートの高さの約 30% だけ移動しています。これにより、この例の距離の割合は 0.3
になります。
レイアウト シフトのスコアは 0.60 x 0.3 = 0.18
です。
予想されるレイアウト シフトと予期しないレイアウト シフト
すべてのレイアウト シフトが悪いわけではありません。実際、多くの動的ウェブ アプリケーションでは、ページ上の要素の開始位置が頻繁に変更されます。レイアウト シフトが悪いのは、ユーザーが想定していない場合のみです。
ユーザーが開始するレイアウト シフト
ユーザー操作(リンクのクリックやタップ、ボタンの押下、検索ボックスへの入力など)に応じて発生するレイアウト シフトは、ユーザーが関係が明確になるようなインタラクションの近くで行われる限り、通常は問題ありません。
たとえば、ユーザー操作によって、完了までにしばらく時間がかかるネットワーク リクエストがトリガーされた場合は、すぐにスペースを作成し、読み込みインジケーターを表示して、リクエスト完了時にレイアウトがシフトすることのないようにすることをおすすめします。ユーザーが、何かが読み込まれていることに気付かなかったり、リソースの準備が整うタイミングがわからなかったりすると、待っている間に別の何か、つまり下から移動してくるものをクリックしようとする可能性があります。
ユーザー入力から 500 ミリ秒以内にレイアウト シフトが発生する場合は、hadRecentInput
フラグが設定されるため、計算から除外できます。
アニメーションと遷移
アニメーションや切り替え効果を適切に使用すると、ページを驚かせることなくページのコンテンツを更新できます。ほとんどの場合、ページ上でコンテンツが突然、予期せず移動すると、ユーザー エクスペリエンスが低下します。しかし、コンテンツがある位置から次の位置に徐々に自然に移動すると、ユーザーは何が起こっているのかをより深く理解し、状態変化をスムーズに進めることができます。
prefers-reduced-motion
のブラウザ設定を必ず遵守してください。アニメーションによって悪影響や注意の問題が生じることがあります。
CSS の transform
プロパティを使用すると、レイアウト シフトをトリガーすることなく要素をアニメーション化できます。
height
プロパティとwidth
プロパティを変更する代わりに、transform: scale()
を使用します。- 要素を移動するには、
top
、right
、bottom
、またはleft
のプロパティを変更せずに、代わりにtransform: translate()
を使用します。
CLS の測定方法
CLS は、ラボまたは現場で測定でき、次のツールで利用できます。
<ph type="x-smartling-placeholder">フィールド ツール
- Chrome のユーザー エクスペリエンス 報告
- PageSpeed Insights
- Search Console(Core Web Vitals) レポート)
web-vitals
JavaScript ライブラリ
ラボツール
JavaScript でレイアウト シフトを測定する
JavaScript でレイアウト シフトを測定するには、Layout Instability API を使用します。
次の例は、PerformanceObserver
を作成して layout-shift
エントリをコンソールに記録する方法を示しています。
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
console.log('Layout shift:', entry);
}
}).observe({type: 'layout-shift', buffered: true});
JavaScript で CLS を測定する
JavaScript で CLS を測定するには、このような想定外の layout-shift
エントリをセッションにグループ化して、最大セッション値を計算する必要があります。CLS の計算方法のリファレンス実装を含む web vitals
JavaScript ライブラリのソースコードをご覧ください。
ほとんどの場合、ページがアンロードされたときの現在の CLS 値がそのページの最終的な CLS 値ですが、次のセクションで説明するように、重要な例外がいくつかあります。web vitals
JavaScript ライブラリは、ウェブ API の制限内で、可能な限りこれらに対応します。
指標と API の違い
- ページがバックグラウンドで読み込まれる場合や、ブラウザがコンテンツを描画する前にバックグラウンドになる場合は、CLS 値をレポートしません。
- ページがバックフォワード キャッシュから復元された場合、CLS 値は 0 にリセットされます。これはユーザーが個別のページ訪問として認識されるためです。
- この API では、iframe 内で発生した移動については
layout-shift
エントリは報告されませんが、指標はページのユーザー エクスペリエンスの一部であるため、報告されます。これは、CrUX と RUM の違いとして示される場合があります。CLS を適切に測定するには、これらを考慮する必要があります。サブフレームは API を使用して、集約のためにlayout-shift
エントリを親フレームに報告できます。
これらの例外に加えて、CLS はページの存続期間全体を測定するため、多少複雑になります。
- ユーザーは、数日、数週間、数か月など、非常に長い時間タブを開いたままにすることがあります。ユーザーがタブを閉じることはありません。
- モバイル オペレーティング システムでは、ブラウザは通常、バックグラウンド タブに対してページ アンロードのコールバックを実行しないため、「最終」のあります。
このようなケースに対応するには、ページがアンロードされるときだけでなく、ページがバックグラウンドにあるときに必ず CLS を報告する必要があります(visibilitychange
イベントでは、この両方のシナリオをカバーします)。このデータを受信する分析システムは、バックエンドで最終的な CLS 値を計算する必要があります。
デベロッパーは、これらすべてのケースを自分で記憶して対処する代わりに、web-vitals
JavaScript ライブラリを使用して CLS を測定できます。CLS は、iframe のケースを除く上記のすべてのケースに対応しています。
import {onCLS} from 'web-vitals';
// Measure and log CLS in all situations
// where it needs to be reported.
onCLS(console.log);
CLS を改善する方法
現場のレイアウト シフトを特定し、ラボデータを使用してそれを最適化する方法について詳しくは、CLS の最適化に関するガイドをご覧ください。
参考情報
- Google パブリッシャー タグに関するレイアウト シフトを最小限に抑えるためのガイダンス
- Understanding Cumulative Layout Shift(Annie Sullivan、Steve Kobes、#PerfMatters、2020 年)
変更履歴
指標の測定に使用される API でバグが見つかることがありますが、指標自体の定義に見つかることもあります。そのため、変更が必要となることがあり、こうした変更は社内のレポートやダッシュボードに改善や回帰として表示されることがあります。
管理しやすくするために、これらの指標の実装または定義に対するすべての変更は、こちらの変更履歴で確認できます。
これらの指標についてフィードバックがある場合は、web-vitals-feedback Google グループからお寄せください。