😭

CLSの改善方法について

2021/03/25に公開

※本記事はweb.devを学習用にまとめたものです。解釈に齟齬等あればコメントください。

Overview

Googleで提唱されているWebページのパフォーマンス指標である CLS (Cumulative Layout Shift) を最適化する具体的な手法について記載する。

CLSとは何かについては、Web Vitalsとは何かを参照してください。

CLSが悪化する5つの原因

1. サイズ指定がされてない動画像

レスポンシブ対応されたサイトでは、横幅が計算値を指定するケースがある。

これにより、「画像を読み込むまでサイズが決定できない」という状況が発生する。

img {
  width: 100%; /* or max-width: 100%; */
  height: auto;
}

従って、画像のダウンロードが終わった瞬間にガクッとレイアウトシフトが起きてしまう。

2. サイズ指定がされてない広告やiframe

広告用スクリプトが読み込まれ、広告コンテンツをDOMに挿入するタイミングでレイアウトシフトが発生する。

また、埋め込みコンテンツやiframeに関しても、事前にサイズを確保できていないとレイアウトシフトが発生してしまう。

3. 動的なコンテンツの挿入

ユーザの操作とは関係のないタイミングで、コンテンツが挿入されたときにレイアウトシフトが発生する。

たとえば、以下のような内容のバナー表示。

  • サインインしてください!
  • 関連のあるコンテンツはこちら
  • iOS/Androidアプリをインストールしてください

4. Web FontsによるFOIT/FOUT

Webフォントをダウンロードしてレンダリングすると、次の2つの方法でレイアウトがシフトする。

  • FOUT: フォールバックフォントが読み込んだフォントと切り替わる
  • FOIT: フォントを読み込まれるまで非表示テキストが表示される

5. アニメーション

CSSプロパティを変化させるようなアニメーションの多用によって、レイアウトシフトは発生する。

例えば、box-shadowbox-sizingを変化させると、再描画を引き起こす。

どのプロパティを変化させると再描画されるのかは、こちらを参照するべし。

https://csstriggers.com/

どうすれば改善する??

1. コンテンツのサイズを指定する

常に動画像のwidthheight属性は指定すべき。

または、アスペクト比を指定したBOXでコンテンツの領域を確保する。

h1 {
  overflow: hidden;
  height: 0;
  padding-top: 56.25%; /* 9 / 16 = 0.5625 */
}

2. 広告や埋め込み要素の配置を改善する

スペースをあらかじめ確保する

広告や埋め込み要素に対して十分なスペースをあらかじめ計算する。

そして、静的にスペース確保することで、コンテンツ読み込まれた後にレイアウトがシフトすることはなくなる。

viewportの上部に広告を配置しない

上部に広告が挟まると、それより下のコンテンツすべてに影響がある。

逆に、広告を中央に配置すれば、それより上のコンテンツが移動する可能性は低い。つまり、レイアウトシフトを防ぐことができる。

3. 動的コンテンツの配置を改善する

広告コンテンツと同様に、あらかじめスペースを確保することで改善可能。

例えば、プレースホルダーやスケルトンUIなどをあらかじめ表示しておくことで、ロード完了時のシフトは発生しない。

4. Fontの読み込み方法を指定する

font-dislayを使用することで、ブラウザがFontをどう扱うかを指定する。

例えばoptionalを指定すると、、、

「ロードが間に合わなければ代替フォントで押し切る」

従ってロード後のレイアウトシフトは起きにくい。

指定内容はこちらの記事が分かりやすい。

https://laboradian.com/show-text-immediately-using-font-display/

また、プリロードさせることで、First Paintまでにダウンロードを間に合わせる。

<link rel=preload>

5. アニメーション

JSでプロパティをいじらずに、transformを使いましょう。

以下のような関数でアニメーションが表現できれば、GPUの力を借りることができるため、重たい描画でCPUを占有するリスクも減る。

  • opacity(透過)
  • translate(移動)
  • rotate(回転)
  • scale(伸縮)

感想

画像やフォントの読み込みが遅れる前提で、領域を確保したり、フォント表示を制御する工夫が必要なんだなと。

最近は広告のせいでCLSに対するエンドユーザーのヘイトも溜まってるはずだから、UXにおけるキーポイントになりそう。

Discussion