PageSpeed InsightsのCLSとは何か?CLSの原因や改善方法

これを書いている2021年6月にGoogleは「ページ エクスペリエンス アップデート(Page Experience Update)」という名称のアップデートを実施しています。
このアップデートの主旨を簡単に言うと「ページが表示された時の体験(Page Experience)を快適なものにしよう」ということです。

具体的にはPageSpeed Insightsで計測したときの以下の3つ(青いラベルが付いている3つ)の評価が検索順位に影響するようになります。
Page Experience

上記3つのそれぞれの改善方法は異なるのですが、今回は「CLS(Cumulative Layout Shift)」の原因や改善方法について解説します。

CLSとは上記の画像内でも書かれている通り、「Cumulative Layout Shift」の略です。
ページ表示時に、「累積的な(Cumulative)、レイアウトの(Layout)、動き(Shift)」がどのぐらい発生するかを示しています。

言葉で説明するよりも見たほうがわかりやすいので、サンプルを作成しました。
以下からの解説とサンプルをご覧ください。

例えば、以下のようなページがあるとします。一度ブラウザで開いて確認してみてください。スマホからでもOKです。
CLSが発生しない良いページのサンプル

以下のような表示になったはずです。これはCLSが発生しない良い例です。
なお、サンプル文章が赤く塗られているのは文章の領域を判別しやすくするためです。
CLSが発生しないページ

次に、以下のページを表示させてみてください。
CLSが発生する悪いページのサンプル

この悪い例の場合は、最初は以下のように表示され、
CLSが発生する前の表示

少し経った後に以下のようになるはずです。
CLSが発生した後の表示

つまり、写真が遅れて表示されることによって、それより後に位置するサンプル文章(赤く塗ってある領域)が下にズレてしまうのです。
レイアウトがズレた量
このズレた量の合計値がCLSです。

ページ表示時にガチャガチャとレイアウトが動くと不快ですよね?
クリックやタップをした時にレイアウトがズレたせいで、意図していない箇所をクリックしてしまった経験は多くの人にあると思います。

Webページというものは「全体が一瞬で、ズレることなく」ディスプレイに表示されるのが最も快適なのです。

CLSが発生する箇所を特定するためにはPageSpeed Insightsや、ChromeのDevTools内にあるLighthouseを使えばすぐにわかります。

PageSpeed Insightsの場合では、CLSが発生した箇所が以下のように表示され、
PageSpeed InsightsでのCLSの発生箇所の特定

Lighthouseの場合では、以下のように表示されます。
LighthouseでのCLSの発生箇所の特定

PageSpeed Insightsは中身はLighthouseを使っていますから、基本的な表示は同じになります。

【補足説明】
両者は測定方法は同じですが、前提となるデバイスや回線速度の設定が異なるため、評価の点数は違ったものになるでしょう。


CLSが発生する原因は以下のようなものが挙げられます。

  1. img要素(画像)によるもの。
  2. iframe要素によるもの。
  3. Ajaxコンテンツによるもの。

この中で最も多いのは画像表示によるズレだと思われますので、以下からは画像を例として解説していきますが、iframe要素やAjaxコンテンツの場合でもCLSの理屈は同じです。
そのため、解決方法も似たようなものになります。

ブラウザがページを表示させる処理には決まった順番があり、その中で画像表示処理は後のほうに位置します。
後になってから画像表示処理がされるから、それまでに表示されていたものの位置がズレるわけです。

しかし、ブラウザが画像表示の処理を後回しにしているのは少しでもページ表示を速くするためなので、これは致し方ありません。
ページを速く表示させるために最も優先すべきなのは「DOMとCSSOMをなるべく早く構築し、それによってページのレイアウトを決定すること」だからです。

では、どうするか?

画像表示によるレイアウトのズレを防ぐには簡単な解決方法があります。
それは、画像の要素(img要素)にwidth属性とheight属性を付けておくことです。

例えば以下のようにimg要素にwidth属性とheight属性がない場合は、

<img src="image/cls.jpg" alt="" />

ブラウザはページのレイアウトを決める際にこの画像の領域をあらかじめ確保しておくことができません。
このコードだけでは画像の横幅や縦幅がわからないからです。
つまり、最初は以下のような表示になってしまいます。
CLSが発生する前の表示
画像が読み込まれるのはもっと後なので、そこで初めて横幅や縦幅が判明することになります。

しかし、以下のようにwidth属性とheight属性を付けておくと、ブラウザは画像の横幅や縦幅をあらかじめ知ることができるので、

<img src="image/cls.jpg" alt="" width="1000" height="480" />

最初の表示時には以下のようにこの画像の領域を空けておくことができます。
つまり、この後に画像が読み込まれてもレイアウトのズレ(CLS)は発生しません
画像の領域を確保
この理屈はimg要素だけのものでなく、iframe要素やAjaxコンテンツの場合でも、表示の縦幅や横幅をあらかじめHTMLやCSSで設定しておけば、CLSの発生は起きなくなります。

ですので、CSSなどで、

width: ●●px;
height: ●●px;

のような指定をきちんとしておけばOKとなります。

提供サポートなど