PageSpeed Insightsスコア改善 - CLS編

:::note info
viviONグループでは、DLsiteやcomipoなど、二次元コンテンツを世の中に届けるためのサービスを運営しています。
ともに働く仲間を募集していますので、興味のある方は[こちら](#一緒に二次元業界を盛り上げていきませんか)まで。
:::

## CLSとは？
Cumulative Layout Shift(キューミュラティヴ レイアウト シフト) = 累積レイアウトシフト

**ページが読み込まれる際に、コンテンツがどれだけ不安定に移動するか(レイアウトシフトが起こっているか)を測定**
![スクリーンショット 2024-05-30 104828.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3803435/cba3f2ac-9b99-bd13-e765-4eadd383df20.png)
※数値が低いほどよい

## なぜ重要？悪いとどうなる？
### **1. UXへの悪影響**
CLSのスコアが低い(=レイアウトシフトが大きい)ページは、ユーザーが「ページを読む」「クリックする」または「その他の操作」を行う際に、予測不能なコンテンツの移動(レイアウトシフト)が発生する。
それにより、ページの読み辛さや誤ったクリックを引き起こすなど、著しくUXを損ねる可能性がある。

![layout-instability2_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3803435/9f24dd88-f254-0b55-e240-fea18ba5e891.gif)
引用元: https://web.dev/articles/cls


### **2. SEOへの影響**

GoogleはCLSをページランクの評価に使用しており、CLSのスコアが高い(=悪い)ページはランキングで低い位置に表示される可能性がある。

## 発生要因は？

**ページ表示範囲内で、既に表示されている要素の開始位置が変更された時に発生。**

（逆に言うと、既に表示されている要素の開始位置が変更されない限りレイアウトシフトはカウントされない）

要因は大きく分けて2つある。

1. 静的コンテンツの非同期読み込み
    サイズを持たない画像、動画、フォント、埋め込み(iframe, object, video, audio, embed, canvasなど)
2. 動的コンテンツの読み込み(挿入・サイズ変更)

より具体的なものだと、

- 画像、動画、フォントなどのコンテンツの読み込み遅延
    - サイズを持たない画像、動画、iframe等の埋め込み
    - スタイルのない状態 or 非表示状態のテキストをフラッシュさせるWebフォントやアイコンフォント
- 動的コンテンツ(広告、ウィジェットなど)の挿入やサイズ変更によるレイアウトの変更
    - 明示的なサイズでスペースを保持しない動的コンテンツ

など

## どのように測定される？

1. 測定タイミング
    > ページの存続期間全体で発生する予期しないレイアウト シフトごとに、*レイアウト シフト スコア*の最大バーストを測定
    > 
    
    > [セッション ウィンドウ](https://web.dev/articles/evolving-cls?hl=ja#why_a_session_window)と呼ばれるレイアウト シフトのバーストとは、各シフトの間隔が 1 秒未満で、合計ウィンドウ時間が最大 5 秒で、1 つ以上の個別のレイアウト シフトが連続して発生することです。
    > 
    
    ![session-window.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3803435/6ce63236-34f1-6db0-b19a-e276ceba2f4e.gif)
引用元: https://web.dev/articles/cls#what-is-cls
    
2. 測定値
    
    画面領域に対して、何％移動したかで測定。
    
    例えば、下記の青枠で囲われている画像の画面占有率を50%とすると、測定値としては50%=**0.5**となる。
    
    ※他にレイアウトシフトが発生してない or 発生したとしても0.5を下回る場合。
    
    ▽画像読み込み前
![スクリーンショット 2024-06-27 172941.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3803435/299bde9e-5ca0-3832-5ce3-7aa3fa806d4f.png)
    
    ▽画像読み込み後
![スクリーンショット 2024-06-27 173004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3803435/1d0dd4ae-34b9-acba-4806-16719ac17793.png)


引用元: https://youtu.be/Z6WiGWDU0nU?si=wyr_3qlZNMe7rqQf
    

## その他注意すべき点
開発中のサイトの機能は、実際のUXとは大きく異なることが多い。

- 個人に最適化されたパーソナライズドコンテンツやサードパーティのコンテンツは、開発環境では本番環境とは異なる動作をすることがよくある
- テスト画像はデベロッパーのブラウザ キャッシュにすでに保存されていることも少なくない
- ローカルで実行される API 呼び出しは非常に高速であるため、遅延に気づかないことも珍しくない

## 改善方法

### 1. コンテンツ(画像・動画・広告など)の適切なサイズ設定
画像、動画、広告等のサイズを適切に指定して、ページの読み込み中にコンテンツが変化しないようにする。

#### 1-1. 画像の場合
CSSの[aspect-ratio](https://developer.mozilla.org/ja/docs/Web/CSS/aspect-ratio)を用いてスペースを確保する。

これによりレスポンシブなどの場合でもCLSを抑えることができる。
        
```html
<img src="" alt="">

<style>
img {
  aspect-ratio: 1 / 2;
}
</style>
```

【おまけ】かつて一般的だった方法
    
```html
<img src="" alt="" height="240" width="450">
```
    
しかし、レスポンシブ対応や高解像度画像を使用した場合など、結局CSSで制御することがほどんどで、**今はあまり役に立っていない**。
    

#### 1-2. iframeや埋め込みの場合

別ドメインやサービスから読み込まれるほぼ全てのもの（広告、動画プレイヤーのウィジェットなど）に対し、それ自体の制御はできないが、その周辺への影響を制御することは可能。

##### 1-2-1. コンテンツサイズが分かる場合
親要素にサイズを指定

```html
<iframe src="">

↓

<div class="iframeWrapper">
  <iframe src="">
</div>

<style>
.iframeWrapper {
  height: 450px;
  width: 250px;
}
</style>
```

##### 1-2-2. コンテンツサイズが分からない場合

###### 例1) 親要素にサイズを指定しつつ溢れる場合は非表示
    
```html
<iframe src="">

↓

<div class="iframeWrapper">
  <iframe src="">
</div>

<style>
.iframeWrapper {
  height: 450px;
  width: 250px;
  overflow: hidden;
}
</style>
```

###### 例2) 親要素のサイズを大きめに指定しておき、多少大きくても問題なく見えるようなデザインにする

つまり、不変の幅と高さ または 可変な幅と高さでも縦横比は固定するなど、決まった領域を確保することが、CLSスコアを最低値にする鍵となる。
    
### 2. **フォントのプリロード**: 使用するフォントを事前に読み込んでおくことで、フォントの遅延によるCLSを軽減できる。

### 3. 動的**コンテンツの確保**: 動的コンテンツ（例: ユーザーコメント、ウィジェット）が読み込まれる前に、適切なスペースを確保することで、レイアウトのシフトを最小限に抑えることができる。


## まとめ

UXやSEOに悪影響を出さないためにも、
画像・動画などの読み込み箇所はもちろん、Webフォント読み込み時や、SNSなど外部サービスのコンテンツ埋め込みも含めて、
極力レイアウトシフトが起こらないよう予めスペースを確保する工夫をしていきましょう！

## 参考元
[Cumulative Layout Shift（CLS）  |  Articles  |  web.dev](https://web.dev/articles/cls?hl=ja)

[How to improve Cumulative Layout Shift for a better page experience](https://youtu.be/Z6WiGWDU0nU?si=cobOIDpawDFvVaSu)


## 一緒に二次元業界を盛り上げていきませんか？
株式会社viviONでは、フロントエンドエンジニアを募集しています。

https://vivion.jp/recruit/

また、フロントエンドエンジニアに限らず、バックエンド・SRE・スマホアプリなど様々なエンジニア職を募集していますので、ぜひ採用情報をご覧ください。