エンジニアを目指す初学者に向けて、わかりやすく解説したブログです。

レイアウトシフト(CLS)の概要、原因、調査方法、改善方法

レイアウトシフトとは

レイアウトシフトとはWebページが表示され始めてから、表示が完全に完了するまでの間に見た目がごちゃごちゃ動く現象のこと。

これが発生すると「ユーザーがボタンを押そうと思ったときにDOMが動いて押し間違えてしまう」という悪いユーザー体験が生まれてしまう。

以下の動画を見ると一発で理解できると思う。

Icon in a page linkCumulative Layout Shift(CLS)  |  Articles  |  web.dev

「このレイアウトシフトが累積されてユーザー体験が悪くなっているよ」という指標がCLSである。

devtoolsでの具体的な調べ方2通り

①発生箇所を特定する

一旦ligthouseを実行してみると、↓の画像のように、右下に「CLS」の絞り込みが現れる。

Image in a image block

絞り込んでみると、具体的にどのDOM要素で発生しているのかを確認することができる。

  1. img要素にwidthとheightを明示していない
  2. 3つの要素でレイアウトシフトが見つかっている
Image in a image block

②どんな感じで発生しているのか理解する

ズレ具合をスローモーションで見たいときがあると思うが、それは Performanceタブで確認することができる。

右下の「Record and reload」を押すとリロードしつつ録画が始まるので、任意のタイミングで止める。

Image in a image block

グラフの中に Layout shiftsがあるので、そこにフォーカスするとスローモーションでどんな感じか確認することができる。

Image in a image block

考えられる原因

およそ2パターンに分類される。

  1. SSR(サーバーサイドレンダリング)ではなくCSR(クライアントサイドレンダリング)をしている
    1. フォント読み込みをクライアントサイドで行ってしまっている
    2. クライアントサイドで何らかのデータを取得してレンダリングしている
      1. ReactやVueなどでfetchしている
      2. Next.jsやNuxt.jsなどのフレームワークを使っているが、CSRとSSRの違いを理解せずに実装している
    3. ローカルストレージから取得したデータをもとにDOMを生成している
  2. 高さや幅のサイズを指定していない
    1. img要素
    2. iframe要素

解決方法

SSR(サーバーサイドレンダリング)ではなくCSR(クライアントサイドレンダリング)をしている

CSRではなく、SSR(サーバーサイドレンダリング)で実装できないか検討する。

特に「データを取得して、それを使って表示している」ような箇所があれば、サーバーサイドでその処理を行えないか検討すると良い。

高さや幅のサイズを指定していない

これは指定すればOK。

「事前に画像のサイズが分からない!」という場合もあると思うが、その場合は2通り考え方がある。

  1. サーバーサイドで画像データを取得し、高さと幅を計算してレンダリングする
  2. 表示領域をあらかじめ固定し、はみ出たところはCSSなどで非表示にする

まとめ

  • レイアウトシフトとは、ページを表示したときに表示されているコンテンツがズレる現象のこと
  • lighthouseタブとperformanceタブで具体的な状況を確認することができる
  • 解決方法
    • CSRにすべき理由がなければSSRで実装しよう
    • widthとheightを指定し忘れていないか確認しよう