Core Web Vitals を測ってサイトを改善しよう

サイトの健全性を示すCore Web Vitalsを確認しながら改善する流れを例を交えて解説します。サイト全体に渡ってCore Web Vitalsをリアルタイムに把握し、ユーザーエクスペリエンスの観点で問題のあるページを効率的に特定、対処しましょう！

# Core Web Vitalsとは？
**Web Vitals**とは、サイトの健全性を示す指標でありGoogleの取り組みによって定義されているもので、その中でも特にユーザーエクスペリエンスの観点の指標が**Core Web Vitals**と呼ばれています。Core Web Vitalsは、サイトで優れたユーザーエクスペリエンスを提供するために必要不可欠な指標とされています。

Core Web Vitalsは継続的にアップデートされていますが、本記事執筆時点においてCore Web Vitalsは3つあり、それぞれ以下のような定義となっています。それぞれの指標の詳細については[Googleの解説](https://web.dev/articles/vitals?hl=ja)を参照してください。

- **Largest Contentful Paint（LCP）**
読み込みのパフォーマンスを測定します。優れたユーザー エクスペリエンスを提供するため、**LCP はページの読み込み開始から 2.5 秒以内**に行われる必要があります。
- **Interaction to Next Paint（INP）**
インタラクティビティを測定します。優れたユーザー エクスペリエンスを提供するには、**ページの INP を 200 ミリ秒以下**にする必要があります。
- **Cumulative Layout Shift（CLS）**
視覚的安定性を測定します。優れたユーザー エクスペリエンスを提供するには、**ページの CLS を 0.1 以下**にする必要があります。

![WebVitals.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535230/8818a1da-cfdb-d550-192e-72e4587675ca.png)


Core Web Vitalsは、2021年より[Googleの検索アルゴリズムにも組み込まれています。](https://developers.google.com/search/blog/2020/11/timing-for-page-experience?hl=ja) 検索順位の変動が業績にも影響を与えるため、サイトの開発者やマーケティングチームはSEO対策としてサイトのCore Web Vitalsを把握し、各指標が基準値（閾値）を超えないように活動していく必要があります。

# Core Web Vitalsの観測における課題
Core Web Vitalsを計測するツールとして代表的なものの１つに[Google PageSpeed Insights](https://pagespeed.web.dev/)があります。特定のページに対してCore Web Vitals悪化の原因などを教えてくれるなど、非常に便利なので重宝している方も多いはずです。

一方、実際のサイトにあたっては乗り越えなければならない壁があります。
- 膨大な数のページがあるサイト全体の中から問題のあるページを特定し、改善する必要がある。1ページずつ問題の有無を確認していくのは現実的ではない
- 多くのユーザーに影響する問題なのか、ごく一部のユーザーで発生する問題なのかを見極め、対応の優先順位をつけなければならない。ユーザーの実際のリアルな体験を把握する必要がある
- サイトの作り（e.g. レイアウト、コンテンツ、フロントエンド/バックエンド実装）の変更や、ネットワークを含むシステムの負荷によってもCore Web Vitalsの値は変わりうるため、ワンショットでの評価でなく、継続的かつリアルタイムに状況を把握する必要がある

このような課題に対応するには、多数かつ環境の異なるユーザーがサイトにアクセスする状況において、サイト全体に渡ってCore Web Vitalsを継続的に収集してリアルタイムに問題の把握と対策ができる手段が必要となります。


# New RelicによるCore Web Vitalsの観測
オブザーバビリティプラットフォームをSaaSで提供するNew Relicは、実際にサイトにアクセスするユーザーの体験をユーザーサイドから収集する機能（New Relic Browser）を提供していいます。

https://docs.newrelic.com/jp/docs/browser/browser-monitoring/getting-started/introduction-browser-monitoring/



New Relic BrowserはJavaScriptで実装されたエージェントがブラウザ内で動作するこことで、ユーザーがサイトにアクセスした際のCore Web Vitalsを含むパフォーマンスやエラーなどをサイト全体に渡って自動的に収集し、リアルタイムに可視化します。ビルトインのUIやダッシュボードを使って品質の悪いページを即座に特定したり、フロントエンドだけでなくバックエンドも含めて一気通貫でトラブルシュートすることが可能になるため、Core Web Vitalsに影響する品質問題の解決を迅速化・効率化できます。

![browser.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535230/eb4241ce-0c1a-9aad-29b5-d8109dfc06c6.png)




---

以降では、非常に簡単なサンプルを使って、Core Web Vitalsの値を確認して原因を特定していく方法を紹介します。Core Web Vitalsを悪化させる要因は多岐に渡りますが、この記事では代表的な例を取り上げて説明します。


なお、例の中では意図的にCore Web Vitalsの値が悪くなるような仕掛けがしてあります。また、サイトにはすでにNew Relicのエージェントが仕込まれ、Core Web Vitalsを含むデータが連携されている前提で進めます。

# 例1: Largest Contentful Paint (LCP) をみる
### LCPの値が悪い例
サイトに表示する最も大きな画像のサイズが非常に大きく、読み込みに時間がかかっているケースを例に取ります。👇の画像はページ読み込み時のイメージです。サイズの大きな画像の読み込みに時間がかかるので、それに引きづられてLCPの値が悪くなります。

![LCP2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535230/eb3c2f21-f2e6-0680-d1d5-d383e089d0ba.gif)


### LCPの悪いページを見つける
New Relicのエージェントが各ユーザー環境のブラウザからパフォーマンスデータを収集すると、サイト全体のCore Web Vitalsの値に加え、各ページごとのCore Web Vitalsの値が確認できます。

下の画像は、サイト全体および各ページ毎のCore Web Vitalsの値を表示した画面ですが、実際にユーザーがアクセスした際のリアルなデータに基づき、**すべてのページの中から即座に問題のあるページが特定できます。これにより時間をかけてサイトのURLを一つ一つ確認したり、やむなく特定のページだけ絞って調査したり、場当たり的に調べるということをせずに効率的に問題に対応できます。**

また、各ページのPV数も合わせて確認できるので、よりPV数が多い、つまりビジネス上インパクトの大きな重要なページで、かつCore Web Vitalsの悪いページの対応を優先できます。

ここでは、画面の赤枠が示す通り、/badlcpというページのLCPが4秒以上で赤くハイライトされており、LCPが悪いことが一目でわかります。

![lcp-browser.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535230/b916b748-1fbb-a0d4-4a5c-b8bc48866b20.png)


### LCPの悪い原因を詳細に分析する
LCPの悪い該当のページを深ぼってみると、そのページのパフォーマンスの詳細が確認できます。

下の図はページロードの際の処理の打ち分けを表したグラフです。処理の種類で色分けされているのでどこに時間がかかっているのかがすぐにわかります。First byte、つまりサーバーからの最初のレスポンスが来るまでの時間は短い（非常に高速）ですが、逆に、その後のフロントエンド側の処理、特にDOM Processingに非常に時間がかかっていることがわかります。

このことから、HTMLを取得したあとのアセットの読み込みなどに時間がかかっていることがわかります。

![lcp-browser-detail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535230/f1853477-66bf-497c-c1f8-3d95d8c8a27d.png)


### クエリを使ってLCPの悪い原因をさらに詳細に分析する
New Relicが収集したデータはクエリ可能な形式で保存されているので、Core Web Vitals関連の情報をもう少し詳細にみてみます。Core Web Vitals関連のデータは、PageViewTimingというイベント（RDBのテーブルのようなもの）として保存されていますので、そこから情報を抽出してみます。

すると、以下画像の赤枠の通り、superxl.pngという画像が約350MBほどあり、ローディングに時間がかかっている結果LCPが悪化しているということがわかります。上述のDOM Processingに時間がかかっていることとも整合が取れます。

![lcp-dashboard.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535230/46e1f0ca-ac5f-f728-d92c-f46e6885a8a4.png)


なお、このテーブルにあるような情報は以下のクエリ（NRQL: New Relic Query Language）を書いて出力できます。PageViewTimingイベントからLCPの値（largestContentfulPaintという属性）とともに、対象となる要素の情報を取得しています。ここでは、どの要素の読み込み時にLCPが大きいか(element)、その要素のパス(elementUrl)、サイズ(elementSize)などを表示しています。


このように、Core Web Vitalsの詳細データを確認するとどの要素がLCPを引き上げているかがわかります。PageViewTimingイベントが持つ属性については[公式ドキュメント](https://docs.newrelic.com/jp/attribute-dictionary/?event=PageViewTiming)を参照してください。

```sql:ページごとのLCPの確認
FROM PageViewTiming 
SELECT percentile(largestContentfulPaint, 75), 
       average(elementSize/1024) as 'Size (MB)' 
WHERE timingName='largestContentfulPaint' 
FACET pageUrl, element, elementUrl 
```

サイトに掲載する商品などの画像は、例えばマーケティングなどの別部門から提供されるケースもあり、誤って非圧縮のまま公開されてしまうということは起こりえますが、そのような場合は今回示したようにLCPを悪化させる要因となります。

今回の例の場合は画像のサイズを縮小することでLCPが改善されるでしょう。今回の例では出てきませんが、バックエンドの最初のレスポンスが遅い場合などもLCPを引き上げる原因になるので、その場合はバックエンドのパフォーマンスを確認していくような対応となります。


LCPの最適化については[Googleのドキュメント](https://web.dev/articles/optimize-lcp?hl=ja)にわかりやすく記載されているのでご参照ください。


# 例2: Interaction to Next Paint (INP) をみる
### INPの値が悪い例
サイトに表示されたボタンをクリックした際、イベントハンドラの処理が重く、その他の処理が待たされているケースを例に取ります。👇がイメージです。

”Click Me!”というラベルのボタンを押下すると、イベントハンドラがボタンのラベルにある数字をインクリメントするようにしてあるのですが、イベントハンドラの処理が重く、後続の処理をブロックした結果、ラベルの変更に時間がかかっている例です。

![INP2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535230/e97fc7b3-9562-d39b-5f21-80606889b9fd.gif)



### INPの悪いページを見つける
INPの悪いページの見つけ方はLCPの場合と同様です。全ページからINPの値でソートすることで、すぐに悪いページを見つけられます。

![inp-browser.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535230/50c4d88f-6ef6-51e3-df57-22302dcf9d16.png)


### INPの悪い原因を詳細に分析する
先ほどと同様にCore Web Vitalsのデータが格納されたPageViewTimingイベントで詳細を確認してみます。下の画像の通り、#btnというIDのボタンに対し、INPの値が非常に悪いことがわかります。このような場合は、このボタンのClickやMouseoverなどのイベントハンドラでブロックされていないかを確認してみると良いでしょう。このようにINPの悪化の原因となっている要素が特定できれば改善することができます。

![inp-dashboard.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535230/f484d9f2-a573-2ee1-f490-69c7cbaf5425.png)


クエリ（NRQL）で書くと👇のような感じです。INPの値（interactionToNextPaint) の他、対象の要素 (eventTarget) を可視化して対象の要素を特定しています。
```sql:ページごとのINPの確認
FROM PageViewTiming 
SELECT average(interactionToNextPaint)
FACET eventTarget, pageUrl 
```

なお、New Relic Browserとは別にNew Relic Syntheticという外形監視機能を利用すると、該当ページにLong Taskが発生しているかどうかがわかります。以下画像の通り、平均で8秒ほどのLong Taskがあることがわかります。クリックハンドラが長時間スレッドを占有していることの分析とも整合が取れます。

![inp-long-running.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535230/d5a7f544-da76-ed67-0d4d-6ea467763d66.png)

クエリ（NRQL）で書くと👇のような感じです。対象のサイトにおけるLong Taskの数や時間を表示しています。
```sql:Long Taskの確認
FROM SyntheticRequest 
SELECT average(longRunningTasksMaxTime), 
       average(longRunningTasksCount)
FACET URL   
```

INPの最適化については[Googleのドキュメント](https://web.dev/articles/optimize-inp?hl=ja)もご参考に。

# 例3: Cumulative Layout Shift (CLS) をみる
### CLSの値が悪い例
サイトの中間の要素（バナー）が遅れて読み込まれることで、先に読み込まれた下の要素がずれるケースを例に取ります。大袈裟すぎる例ですが、👇がイメージです。赤いBANNERというバナーが遅れてくるので下の画像がずれています。ここまでずれることはなくとも、間にボタンや入力フィールドなどがあると誤操作の原因になります。

![CLS2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535230/fbc0a9f6-d242-7676-6cb2-190e8627439f.gif)


### CLSの悪いページを見つける
こちらも先ほどまでと同様です。CLSでソートすればすぐに対処すべきページが特定できます。

![cls-browser.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535230/769d643e-6d37-6873-1ec3-4347695c09fc.png)


### CLSの悪い原因を詳細に分析する
先ほどと同様にCore Web Vitalsのデータが格納されたPageViewTimingイベントで詳細を確認してみます。以下の通り、#productContainerというIDの領域（バナーの読み込み遅延によって、下にずれた画像があるテーブル）のMax Largest Shift Valueが 大きく、位置がずれていることがわかります。この要素の周辺から、位置がずれた原因（今回の場合はすぐ上のバナー）を探すとCLSを改善することができます。

![cls-dashboard.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535230/f512e3ac-0ec4-cd68-3f52-d1328476414b.png)


クエリ（NRQL）で書くと👇のような感じです。CLSの値（cumulativeLayoutShift）の他、対象要素（largestShiftTarget）などの特定ができます。このように要素を特定していくことでCLS悪化の要因を徐々に取り除いていくことができます。
```sql:ページごとのLCPの確認
FROM PageViewTiming 
SELECT max(largestShiftValue), 
       percentile(cumulativeLayoutShift, 75) 
WHERE timingName='cumulativeLayoutShift' 
FACET largestShiftTarget,  pageUrl
```

CLSの最適化に関する[Googleのドキュメント](https://web.dev/articles/optimize-cls?hl=ja)もご参考に。


# まとめ
サイトの全ページに渡ってCore Web Vitalsを確認し、各重要指標ごとに値の悪いページと原因を特定しながら改善する例を説明しました。リアルなサイトではこの簡単なサンプルよりも見るべきところはもっと多岐に渡りますが、Core Web Vitalsの問題を把握し、改善する一つの方法として参考になれば幸いです。


今回はNew Relicでみる方法を中心に説明しましたが、Google PageSpeed Insightsなどのツールも併用して、それぞれが得意なところを上手く活用するとより効率的に分析ができます。また、クエリ（NRQL）で分析したような情報は、調査の度に書く必要がないようにダッシュボードやアラートにあらかじめまとめておくのも良い方法です。その他、ビルトインのUI以外にも[Core Web Vitals分析用のダッシュボードテンプレート](https://newrelic.com/instant-observability/cwv-example)なども提供していますのでご覧ください。


Core Web VitalsはGoogle検索順序にも反映され、ビジネスに直接的な影響を与えるのでケアすべきであるのは冒頭に記載した通りです。加えて、**Core Web Vitalsはユーザーエクスペリエンスを表す指標であるという性質上、SEO対策の重要度が低いサイトであっても、利用者に最高の体験を届けるにはケアしていくべき指標**であると言えるのではないでしょうか。Core Web Vitalsをきちんと計測して改善していきましょう。


👇の公式ブログの解説もご参考に。

https://newrelic.com/jp/blog/best-practices/customer-satisfaction-with-core-web-vitals

:::note info
無料のアカウントで試してみよう！
[New Relic フリープランで始めるオブザーバビリティ！
](https://qiita.com/ktst79/items/5ee74b34e6adb8a7a6fa)
:::
:::note info
New Relic株式会社の[X(旧Twitter)](https://x.com/NewRelicJapan) や [Qiita Organization](https://qiita.com/organizations/newrelic)では、
新機能を含む活用方法を公開していますので、ぜひフォローをお願いします。
:::