# パフォーマンス指標
# Core Web Vitals
Core Web Vitalsとは、Web Vitalsにおいて重要となるLCP、FID、CLSという3つの指標になります。Core Web Vitalsの指標を準拠することで、パフォーマンスが改善され、質の高いユーザー体験を提供することができます。
出典: Introducing Web Vitals: essential metrics for a healthy site (opens new window)
パフォーマンス施策を考える際は、Core Web Vitalsの指標がどのように測定され、ユーザー体験にどのように影響するのか把握する必要があります。さらに、これらの指標は実際のユーザーから収集したField Dataと特定環境化のLab Dataによって結果が異なります。各指標の性質、収集データの種類と目的、計測ツールを知ることで、適切なパフォーマンス改善ができるようになることが重要となります。この章では、各指標の見方を見ていきたいと思います。
# LCP
LCP(Largest Contentful Paint)とは、ページ内で重要な要素がどれだけ早く表示されるかを表す指標です。重要な要素とは、ビューポート内に表示される最も大きい画像または、テスキスのブロックを指します。
似たような指標で、FCP(First Contentful Paint)があります。FCPは、画像やテキストなどの何らかのコンテンツが一番はじめに表示するまでの時間を計測します。一方、LCPはページ内の最大のコンテンツが表示するまでの時間を計測します。FCPが最初のコンテンツの指標であるのに対し、LCPは最大のコンテンツの指標となります。 例えば、次のようなサイトではFCPが最初のテキストに対し、LCPは最終的な画像になります。
出典: Largest Contentful Paint(LCP) (opens new window)
LCPにおける推奨されるスコアは、2.5s
以内と言われています。4s
を超えると改善が必要とされます。
出典: Largest Contentful Paint(LCP) (opens new window)
試しに、YahooニュースをPageSpeed Insights (opens new window)で計測すると次のような結果になります。
LCPの計測時間が1.4s
でGoodの評価を得ていることが分かります。また、LCPのコンテンツがトップの天気画像になっていることが分かります。
出典: Yahooニュース (opens new window)
# FID
FID(First Input Delay)とは、ページ読み込み時の最初の応答性を測定するための指標です。具体的には、クリックやタップ、キーの押下などによる入力イベントからブラウザがイベントハンドラの処理を開始するまでの時間を測定します。似たような指標で、TTI(Time to Interactive)があります。TTIは、FCPから開始して実際にユーザーが操作可能になるまでの時間を指します。Reactの場合、ハイドレーションが完了してイベントのバインディングがされている状態を指します。TTIは操作可能になるまでの時間を測定するのに対し、FIDは、最初のアクションからブラウザが応答するまでの遅延時間を計測します。そのため、FIDの値は低い方がパフォーマンスが優れていると言えます。
出典: First Input Delay (FID) (opens new window)
FIDのスコアは、100ms
以下が推奨されています。300ms
を超えると改善が必要とされます。
出典: First Input Delay (FID) (opens new window)
先ほどのYahooニュースのPageSpeed Insightsを見ると、20ms
に抑えられていることが分かります。
FIDは、スクロールやズームなどの動作に対しては測定しません。クリックやタップ、キーの押下などの入力イベントのみを測定対象としています。初回の応答性を評価することで、UXに優れているかを測定することができます。これは、RAILパフォーマンスモデル (opens new window)の応答性(Response)に焦点を当てており、応答性を高めることでパフォーマンスが優れていると判断することができます。
# CLS
CLS(Cumulative Layout Shift)とは、ページの表示中に発生するレイアウトのズレを測定する指標です。例えば、画像の読み込みが遅れることで、レイアウトのガタつきが発生してしまうケースなどが当てはまります。レイアウトが変わることで、ユーザが意図しない操作をする可能性もあるでしょう。極端な例だと、誤って自分の意思とは異なるボタンを押下してしまうケースなどが考えられます。
出典: How CLS optimizations increased Yahoo! JAPAN News's page views per session by 15% (opens new window)
CLSのスコアは、0.1
以下が推奨されています。0.25s
以上になると改善が必要となります。
CLSのスコアは、レイアウトのズレで計算しているので低い方がパフォーマンスが優れているとされます。Yahooニュースの例だと、CLSが0
なのでパフォーマンスの最適化がされていることが分かります。
# INP
INP(Interaction to Next Paint)とは、ページの読み込みからユーザがページを離脱するまでに発生する入力の応答性を評価する指標です。INPは、入力からイベントハンドラが開始するまでの遅延時間、コードの処理時間、処理終了後にブラウザが表示するまでの遅延時間を評価します。FIDとの違いは、FIDが最初の応答性を評価するのに対して、INPはユーザが離脱するまでの間の応答性を評価します。また、FIDは入力からの遅延時間のみ評価しますが、INPは、入力からの遅延時間、処理時間、ブラウザの表示の遅延時間の3つを評価します。そのため、INPはFIDを包括する指標になり、より信頼性の高い測定になっています。
評価の範囲 | 評価の対象 | |
---|---|---|
FID | 最初の応答性 | 入力からの遅延時間 |
INP | 最初から離脱するまでの応答性 | 入力からの遅延時間、処理時間、ブラウザの表示の遅延時間 |
INPのスコアは、200ms
が推奨さています。500ms
以上になると改善が必要になります。
出典: Interaction to Next Paint (INP) (opens new window)
Yahooニュースを見ると、239ms
なので推奨されるスコアよりも少し上回っていることが分かります。
# その他の指標
# TTFB
TTFB(Time to First Byte)とは、クライアントがリクエストを開始してからサーバーが最初のレスポンスを応答するまでの指標です。FCPやLCPと違い、一番最初に応答されるレスポンスまでの時間を評価します。そのため、DNSルックアップやサーバでのレンダリング、ナビゲーションに関わる処理に影響を受けます。
TTFBのスコアは、800ms
以下が推奨されます。TTFBはCore Web Vitalsの指標には含まれませんが、TTFBの改善はFCPやLCPの改善にも繋がるため、重要な要素になります。
Yahooニュースの例だと、TTFBが0.4s
でGoodの評価になっていることが分かります。
# FCP
FCP(First Contentful Pain)とは、ページが読み込まれてからページ内のいずれかのコンテンツが表示するまでの時間を指します。コンテンツはテキストや画像などが含まれます。例えば、下記のサイトの場合、ヘッダーがレンダリングされたタイミングでFCPが発生していることが分かります。
FCPは、ページに表示される最初のコンテンツを測定するための指標です。ページのメインのコンテンツが指標となるLCPとは、測定対象が異なります。
FCPのスコアは、1.8s
以下が推奨されます。
出典: First Contentful Paint (FCP) (opens new window)
Yahooニュースの例だと、FCPが1.0s
でGoodの評価になっていることが分かります。
# TTI
TTI(Time to Interactive)とは、ユーザーが画面を操作できるようになるまでの時間を測定します。FCPが発生してから開始し、メインスレッドで一番長く時間がかかっているタスクが終了するまでの時間を評価します。
出典: Time to Interactive (TTI) (opens new window)
Reactを使ったSSRでは、ハイドレーションが完了するまでの時間を指します。SSRではHTMLを返すため、見た目上、操作できるように感じます。しかし、実際には、JavaScriptをダウンロードしてイベントをバインディングするまでアプリケーションは機能しません。TTIのスコアは、5s
以下が推奨されます。JavaScriptを削減し、メインスレッドの処理を効率化することでTTIを改善することができます。
# 計測方法
Core Web Vitalsでは、Field DataとLab Dataという二つの計測方法で各指標を評価しています。それぞれのデータの用途は異なるため、計測ツールで測定しているときはどちらのデータを収集しているかを把握する必要があります。
# Field Data
Field Dataとは、実際のユーザー環境に基づいて計測されます。匿名化されたユーザーのデータを収集して、過去28日間の平均値で評価します。仮に、十分なデータ量がないと計測することはできません。
Field Dataは、実際のユーザー体験に直結するデータとなります。そのため、パフォーマンス施策の最終的な改善目標はField Dataを設定する必要があります。Field Dataは、全体の75%のユーザーが推奨スコアを満たしているとGoodの評価になります。例えば、次のような指標の場合、88%のユーザーが推奨スコアを獲得しているためGoodの評価になっています。
出典: Why lab and field data can be different (and what to do about it) (opens new window)
PageSpeed Insightsでは、実際のユーザーの環境で評価する
という項目がField Dataになります。
Field Dataは過去のデータに基づいて評価されるため、パフォーマンスの改善を行っても、すぐ反映されるとは限りません。施策ごとに効果を測定するためには、スケジュールを管理して評価する必要があるでしょう。
# Lab Data
Lab Dataとは、特定の環境化で計測されたデータになります。例えば、ローカルのPCで測定したデータや、CIなどの特定の環境下で実施したデータが当てはまります。Lab Dataの目的は、より具体的で、Field Dataだけでは特定しにくい要素を検証することです。例えば、JavaScriptの最適化や画像の最適化、HTML属性の設定や、メインスレッドでの処理などを詳しく調べることができます。これらのデータをもとにパフォーマンス施策を行うことで、結果としてField Dataの改善に繋げることができます。
Lab Dataの収集は、Lighthouse (opens new window)などで計測することができます。PageSpeed Insightsでは、Lighthouseを内部で使用しているため、Lab Dataの結果も見ることができます。
# 計測ツール
Core Web Vitalsの指標を計測できるツールは以下のようなものがあります。
- PageSpeed Insights (opens new window)
- Search Console ( Core Web Vitals report)
- Lighthouse (opens new window)
- Lighthouse CI (opens new window)
- Web Vitals Chrome (opens new window)
Field DataとLab Dataを取得したい場合は、PageSpeed Insightsで計測することができます。PageSpeed InsightsはURLを入力するだけで実施できるため、すでに運用しているサイトを計測する場合に有効でしょう。
出典: PageSpeed Insights (opens new window)
Lab Dataを取得して詳細な検証が必要な場合は、Lighthouseで具体的な状況を確認することができます。Lighthouseは、Chrome DevToolsに組み込まれているため、ローカル環境での計測をすることができます。
その他にも、Chrome DevToolsでは、ConsoleのRendering
タブのCore Web Vitals
をチェックすることで、現在表示しているサイトのCore Web Vitalの指標をリアルタイムで見ることができます。
ローカル環境以外でも、Lighthouse CI (opens new window)を使ってLighthouseをCIに紐づけることで、定期的なLab Dataの観測をすることができます。特定の環境下で定期的にチェックすることで、パフォーマンスの推移を把握することができます。Field Dataの場合、過去の実際のユーザーデータから評価するため、パフォーマンスが低下したタイミングを見逃す可能性があります。CIでLab Dataを逐一チェックすることで、大きな変化があったタイミングを検知し、すぐに対応をすることができます。
出典: GoogleChrome/lighthouse-ci (opens new window)
計測ツールによって収集するデータや用途は異なります。Field DataとLab Dataどちらのデータなのかを意識し、継続的に計測できる環境を整えることが重要となります。
# 計測API
上記のようなツール以外にも、JavaScriptでCore Web Vitalsの指標を計測することができます。例えば、LCPの測定を行うには、Largest Contentful Paint API (opens new window)を使用することができます。
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
console.log('LCP candidate:', entry.startTime, entry);
}
}).observe({type: 'largest-contentful-paint', buffered: true});
NPMパッケージのweb-vitals (opens new window)では、次のように書くことができます。
import {onLCP} from 'web-vitals';
onLCP(console.log);
また、Core Web Vitalsの指標以外で独自にデータを取得したい場合は、以下のようなAPIを使うことで、任意のタイミングでデータを収集することができます。