CLS

ページの読み込み中に発生する予期しないレイアウトのずれを測定する Core Web Vitals の指標

パフォーマンスSEO

CLS とは

CLS (Cumulative Layout Shift) は、ページの読み込み中や操作中に発生する予期しないレイアウトのずれ (要素の位置変動) の累積スコアを測定する Core Web Vitals の指標である。Google が 2020 年に導入し、検索ランキングの要因の 1 つになっている。

スコア 評価
0〜0.1 良好 (Good)
0.1〜0.25 改善が必要 (Needs Improvement)
0.25 以上 不良 (Poor)

なぜ CLS が問題なのか

記事を読んでいる最中に、広告が読み込まれてテキストが下にずれる。「購入」ボタンを押そうとした瞬間に、上に画像が表示されて「キャンセル」ボタンを押してしまう。これがレイアウトシフトだ。ユーザー体験を著しく損なう。

CLS の主な原因と対策

1. 画像・動画のサイズ未指定

<!-- ❌ サイズ未指定: 画像読み込み後にレイアウトがずれる -->
<img src="hero.jpg" alt="Hero image">

<!-- ✅ width/height を指定: ブラウザが事前にスペースを確保 -->
<img src="hero.jpg" alt="Hero image" width="1200" height="630">

<!-- ✅ CSS の aspect-ratio でも可 -->
<style>
  .hero-img { aspect-ratio: 16 / 9; width: 100%; }
</style>

2. Web フォントの FOUT/FOIT

Web フォントの読み込み中にシステムフォントで表示され、読み込み完了後にフォントが切り替わるとレイアウトがずれる。

/* font-display: swap + サイズ調整 */
@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/custom.woff2') format('woff2');
  font-display: swap;
  size-adjust: 105%; /* システムフォントとのサイズ差を調整 */
}

<link rel="preload"> でフォントを先読みし、切り替えのタイミングを早める。

3. 広告枠のサイズ未確保

/* 広告枠の最小サイズを CSS で確保 */
.ad-slot {
  min-height: 250px; /* 広告の最小高さ */
  background-color: #f5f5f5;
}

4. 動的コンテンツの挿入

// ❌ ページ上部に動的にバナーを挿入 → 全コンテンツが下にずれる
document.body.prepend(createBanner());

// ✅ 固定の高さを持つコンテナを事前に配置
<div id="banner-slot" style="min-height: 60px;"></div>

CLS の測定方法

# Lighthouse で測定
npx lighthouse https://example.com --only-categories=performance

# Chrome DevTools → Performance タブ → Layout Shift を確認
# PageSpeed Insights で実ユーザーデータ (CrUX) を確認
// JavaScript で CLS をリアルタイム測定
new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (!(entry as any).hadRecentInput) {
      console.log('Layout shift:', (entry as any).value);
    }
  }
}).observe({ type: 'layout-shift', buffered: true });

Next.js / React での CLS 対策

  • next/image コンポーネントは自動的に width / height を設定し、CLS を防ぐ
  • next/font は Web フォントを最適化し、FOUT を最小化する
  • Suspense の fallback に固定サイズのスケルトン UI を表示する

より深く学ぶには関連書籍が役立つ。

関連用語