ノンカフェインであなたにやさしい

Ruby,Rails,HTML,CSS,Reactなど

レスポンシブサイトでlazysizesを使い画像遅延読み込みをした時のCore Web Vitals CLS対策

Core Web Vitalsの値、気にしてますか? レスポンシブでCLS対策をする時の対応を書きます。

CLSとは?

Cumulative Layout Shift は、ページがどのくらい安定しているように感じられるかを表します。視覚的な安定性を測定し、表示されるページ コンテンツにおける予期しないレイアウトのずれの量を定量化します。

developers-jp.googleblog.com

画像の読み込みや、コンテンツの遅延読み込みなどでサイトの要素がズレる量のことです。 基本的には画像サイズを指定してあげることでズレはなくなります。

画像遅延読み込みとの兼ね合い

lazysizesというプラグインを使い画像遅延読み込みをしていますが、読み込まれるまで1x1pxの透過画像を置いておくのがスタンダードです。

<img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-src="本来の画像URL" class="lazyload" width="200" height="100">

github.com

レスポンシブで1x1px透過画像を先読みする場合の不具合

レスポンシブにしたいと、画像を width: 100%; height: auto; にすると
読込中 1x1px 画像のアスペクト比を保持して横100%になってしまいます。

読み込まれるまで高さがwidthと同じになってしまう
<img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-src="本来の画像URL" class="lazyload" width="200" height="100">

<style>
  img {
    width: 100%;
    height: auto;
  }
</style>

サンプル レスポンシブサイトでlazysizesを使い画像遅延読み込みをした時のCore Web Vitals CLS対策 サンプル

このサンプルでは1枚目の画像も 1:1 の高さを保持してしまっているため画像読み込み後にズレが生じてCLSが0.095になっています。
※サンプルなのでそこまで悪い数字ではないですが f:id:kuronekopunk:20201211231400p:plain

対策

  • imgタグのwidth, heightは幅320pxの時のアスペクト比で入れる
  • height: auto; はlazyloadが完了してから設定する

下記のようになります。

<img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-src="本来の画像URL" class="lazyload" width="320" height="160">

<style>
  img {
    width: 100%;
  }
  /* lazyload完了後に付与されるクラス */
  img.lazyloaded {
    height: auto;
  }
</style>

サンプル レスポンシブサイトでlazysizesを使い画像遅延読み込みをした時のCore Web Vitals CLS対策 サンプル

CLSが0.009になりました。

f:id:kuronekopunk:20201211231454p:plain

注意

imgタグのwidth, heightは幅320pxの時のアスペクト比で入れる

というのはLighthouseのmobileで計測する時のブラウザ幅です。
違うブラウザ幅だとCLSのガタつきが発生するためユーザーにとって最適とは言えません。
事前にアスペクト比が分かっているならpadding-topを%で指定して先にサイズを確保しておくなどありますが、運用面でコストが高くなってしまいます。
ケースに合った対応を心がけましょう。