PageSpeed Insightsスコア改善 - LCP編

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

## LCP(Largest Contentful Paint)とは？
「**ページの読み込み速度**」と「**ユーザー体験**」を数値化した指標。
※SEOにも影響を与える指標

より具体的にいうと、
**ビューポート内で最も大きなコンテンツ**(画像またはテキスト群)**が、完全に表示されるまでの時間**を示したもの。

つまり、**ユーザーが「読み込みが完了した」と感じる瞬間と密接に関連している数値**のため、スコアが低い場合は早急に改善したい項目。

![good-lcp-values.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3803435/94b2235c-165b-c8bf-7c2f-a6a715bc6ed6.png)



:::note info
loadやDOMContentLoaded、FCPとの違いは？

[load](https://developer.mozilla.org/docs/Web/Events/load) や [DOMContentLoaded](https://developer.mozilla.org/docs/Web/Events/DOMContentLoaded) だと、ユーザーに表示されるものと必ずしも一致しない。（読んでる記事の下に大きな画像があり、待ち時間が発生したとしてもユーザーからしたらどうでもいいため load は不適切。 DOMContentLoaded ではCSS,画像,JSなどがレンダリングされてない可能性があるため早すぎる。）

[First Contentful Paint（FCP）](https://web.dev/articles/fcp?hl=ja)などの「ユーザー中心のパフォーマンス指標」では、最初の描画部分しか取得されないためあまり参考にならない。（例としてローディング中のスピナーが表示される場合など）
:::

## 測定方法は？
[PageSpeed Insights](https://pagespeed.web.dev/?hl=ja)やLighthouseはもちろん、
ChromeのDevToolsからも確認できる。

1. 右上のメニューから または ⌘Cmd(Ctrl) + ⇧Shift + P で「コマンドを実行」
![スクリーンショット 2024-08-29 18.02.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3803435/4033ba1f-b2fe-335d-e9e0-f2731d5a0f76.png)
2. 入力欄に「オーバーレイ」と入力して実行
![スクリーンショット 2024-08-29 18.05.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3803435/15c3ebbf-00d4-55fa-35f7-b749c6ae76ba.png)
3. LCPの数値が表示される 
![スクリーンショット 2024-08-29 18.06.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3803435/c9606d1b-5265-0f12-d464-a768759ef202.png)

## LCPが低下する原因は？
### 1. 画像が最適化されていない
1. ファイルサイズが大きすぎる
言うまでもないが画像のファイルサイズが大きいとサーバーに負荷がかかり、読み込み速度が遅くなる。その結果、LCPの低下にも繋がる。
→ **コンテンツ内の画像を全て見直し、1MB以上など極端に大きなサイズのものがないか確認しよう**。
2. 適切な拡張子になっていない
何も考えずに .jpg または .png にしている場合は要注意。
**適切な拡張子を選ばないと、画像のファイルサイズが大きくなる**。
3. 圧縮されていない 
圧縮してないと**不要なバイトが含まれる分ファイルサイズが大きくなる**。
4. 正しいサイズの画像を提供する
よくあるのは、実際に表示されるサイズより画像サイズが大きいケース。
※極端な例だが、実際には320px固定幅で表示している画像のサイズが1280pxになっているなど。
無駄に大きければその分読み込みに時間がかかり、逆に小さいと荒い画像が表示されてしまう。
そのため `<picture>`要素と `<source>`要素を使って、**デバイスや表示サイズに応じて適切なサイズの画像を表示する**ようにする。
5. プリロードを適切に行なっていない
LCPは、ビューポート内の最大のコンテンツが完全に表示されるまでの時間を測定したものであり、一般的には画像であることが多い。
そのため、**画像の読み込みが遅いとその分LCPのスコアが下がることになる**。

### 2. JavaScriptやCSS、Webフォントが最適化されていない（内部・外部共通）
1. 使用していないものが読み込まれている
JavaScriptやCSSの実行・解析のために、サーバーやブラウザに負荷がかかるため、多いとその分だけコンテンツの読み込み速度が低下する。
そのため、不要な記述や処理がないか見直そう。
2. 読み込み方法が最適化されてない
例えばファーストビュー内に必要なCSS記述はインライン、他は遅延読み込み・非同期読み込みを行いレンダリングブロックを回避するなど、内容に応じて読み込みタイミングを変える。
3. 圧縮されていない
ファイルサイズが大きいと、それだけ解析に時間がかかってしまい、読み込み速度の低下に繋がる。
### 3. サーバーのスペックが低い
処理速度が遅いサーバーを使っていると、応答に時間がかかり、ページの読み込み速度も低下する。(フロントエンド領域外のため詳細は割愛)

## 改善方法
1. サーバーの最適化(遅さ改善)
    - サーバー側のロジックと操作を最低限に抑える
    - キャッシュを活用する（画像、スタイル、スクリプトなどの静的ファイルのキャッシュ有効期間を長めにするなど）
2. 画像、CSS、JavaScript、Webフォントの最適化
    - CDNの活用
        - ファーストビューに必要で、先んじて読み込みたい場合は下記プリフェッチを使う
        ▽例
        ```html
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.0/css/swiper.min.css" />
        ↓
        <link rel="dns-prefetch" href="https://cdnjs.cloudflare.com">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.0/css/swiper.min.css" />
        ```
        
    - Service Workerの活用（Service Workerとはブラウザ内でネットワークリクエストを直接インターセプトして応答できるようにする特別なJSファイル）
    - ファーストビュー内のレンダリングを早める
        - 使用されてないCSS, JSなどの削除 または 読み込みタイミングを遅らせる
            
            遅延 > 非同期（非同期の場合、スクリプトによってはレンダリングを中断する可能性があるため、待ってもいい場合は遅延の方が効果的）
            
            - 遅延
                
                defer(遅延読み込み)は、付与したスクリプトを非同期で読み込みつつ、HTML解析完了まで実行を遅延させる。
                そのため、ファーストビューの描画に必要なスクリプトに適している。
                
                ```html
                <script src="..."></script>
                ↓
                <script defer src="..."></script>
                ```
                
            - 非同期
                
                async(非同期読み込み)は、付与したスクリプトを非同期で読み込み、完了次第すぐに実行される。（HTML解析とは独立している）
                そのため、ファーストビューの描画に関係しないスクリプトに適している。
                
                ```html
                <script src="..."></script>
                ↓
                <script async src="..."></script>
                ```
                
        - ファーストビューのレンダリングに必要な記述をヘッダーに直書きする
            
            ただし全てを直書きしてるとファイルサイズが肥大化する可能性があるため、必要に応じて下記プリロードも活用（乱用すると意味なくなるので必要なものだけに使用）
            
            ```html
            <link rel="preload" href="..." as="style" />
            <link rel="preload" href="..." as="script" />
            <link rel="preload" href="..." as="image" />
            <link rel="preload" href="..." as="video" />
            <link rel="preload" href="..." as="font" type="font/woff2" />
            ```
            
    - 画像の最適化
        - 実際の表示サイズ以上に大きい画像を使用しない
        - 可能な限り圧縮する
            以下のようなサービスやツールを使って**必ず圧縮を行う**。
https://squoosh.app/
https://tinypng.com/            
        - ファーストビュー内にない画像は遅延読み込みを行う（※ファーストビュー内の画像にはスコア悪化に繋がるため使用禁止）
            ```html
            <img loading="lazy" src="..." alt="" />
            ```
        - 適切な拡張子を使用する
        対応ブラウザのサポート外でなければ基本は `.webp`,
        写真等の色数が多い画像は `jpg`,
        シンプルなロゴ・アイコンなど、ベクター画像は `svg`,
        線がはっきりしているロゴ・アイコン・イラスト画像は `png`,
        等のように**適切に拡張子を使い分けることでファイルサイズを抑えられる**。

## まとめ
LCPはCore Web Vitals(実際のUXを測定する指標)の一つで、検索ランキングにも影響を与える要素としてGoogleも改善を強く勧めている項目です。
その分パフォーマンススコアにおいて多くの割合を占めていますが、改善方法は意外と実施しやすいものが多いため、スコア改善において中々コスパの良い項目だと思います！
そのため、優先的に進めてスコアもUXも良くしていきましょう！

## 参考元
[Largest Contentful Paint（LCP）  |  Articles  |  web.dev](https://web.dev/articles/lcp?hl=ja)
[How to improve Largest Contentful Paint for a better page experience](https://youtu.be/480m72yjZv8?si=ewCdP_7ZCMOIoccP)

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

https://vivion.jp/recruit/

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