Chrome UX Report APIによるCore Web Vitalsの計測

UI開発者 加藤

Googleが発表した「Core Web Vitals」、すでにその言葉を聞いたことがある方は多いかもしれません。では「Chrome User Experience Report(以下、CrUX)」はご存じでしょうか?

CrUXはBigQueryに保存されているPublic Google BigQuery projectPageSpeed Insightsのデータを組み合わせて、ページごとの定量的な評価をひとまとめにしたビッグデータです。Google Cloud Platform(GCP)のプロジェクトを作成すれば、だれでも、さまざまなサイトのデータを参照できます。

CrUxからは2020年8月現在、Core Web VitalLCPsを構成する3つの指標(LCPCLSFID)にFCPを加えた4つの指標に関するデータを得ることができます。あくまでPageSpeed Insightsで得られた範囲のデータであるという前提のもとですが、CrUXを利用すればCore Web Vitalsとして定義されている指標に関するフィールドデータを計測できるということになります。また、今後は「UX Report」という名の通り、ロード時のパフォーマンスに関する指標だけでなく、UXに関連した指標も今後追加される予定のようです。

CrUXのデータを参照するには4つの方法が存在します。今回はその中から7月に発表されたCrUX APIを使ってデータを参照する方法を紹介します。CrUX APIはRESTfulなAPIですので、指定のURLへリクエストを送ることができれば、あとはお好みの環境で実行することができ、返却されたレスポンスデータをどう使うかも自由にカスタマイズすることができます。BigQueryの操作やSQLに慣れていない方にはおススメです。

※ CrUX APIから得られるデータは直近28日間までとなっています。それよりも過去のデータを参照したい場合はBigQueryを使用しましょう。

JavaScriptでAPIを使う

API経由でデータを得るためにはまずGCP上でプロジェクトを1つ作成しAPIキーを発行する必要があります。認証情報のページからAPIキーを発行しておきましょう。また、同プロジェクトでChrome UX Report APIが有効化されている必要があります。こちらも有効化しておきましょう。

準備ができたらあとは一般的なRESTful APIと同様に指定のURLにリクエストを行うだけです。

リクエスト

エンドポイントとなるURLは「https://chromeuxreport.googleapis.com/v1/records:queryRecord」です。このURLに先ほど作成したAPIキーの情報と対象のURLなどをPOSTします。リクエストのBodyには以下の情報を含められます。

origin もしくは url

urlは特定のページのデータを取得したい場合に使用しますが、originは指定したURLの配下に存在するページを集約したデータを取得します。

※指定したオリジン、URLのデータがCrUX Reportのデータ上に十分存在しない場合はリクエスト時に404エラーが返却されます。

effectiveConnectionType

ネットワークスピードでフィルタリングできます。指定できる値は「effective-connection-types」で定義されている4つのうちいずれかです。指定しない場合はすべてが対象になります。

  • slow-2G
  • 2G
  • 3G
  • 4G

formFactor

デバイスのサイズでフィルタリングできます。指定できる値は以下の4つのうちいずれかです。指定しない場合はALL_FORM_FACTORSが適用されます。

  • ALL_FORM_FACTORS
  • PHONE
  • DESKTOP
  • TABLET

metrics

レスポンスに含めたい指標をあらかじめ指定することができます。指定できる値は以下の4つのうちいずれかです。(指定しない場合はすべてが含まれます)

  • first_contentful_paint
  • first_input_delay
  • largest_contentful_paint
  • cumulative_layout_shift

関係性が分かりやすいようにTypeScriptの型表現を加えるとリクエストは以下のようになります。

export type FormFactor = 'ALL_FORM_FACTORS' | 'PHONE' | 'DESKTOP' | 'TABLET';
export type EffectiveConnectionType = 'slow-2G' | '2G' | '3G' | '4G';
export type MetricsType = 'first_contentful_paint' | 'first_input_delay' | 'largest_contentful_paint' | 'cumulative_layout_shift';

export interface RequestBody {
    origin?: string
    url?: string
    effectiveConnectionType?: EffectiveConnectionType
    formFactor?: FormFactor
    metrics?: MetricsType
}

/**
 * @param body
 * @param apiKey
 * @return {Promise<Record>}
 */
function load(body: RequestBody, apiKey: string) {
    return fetch('https://chromeuxreport.googleapis.com/v1/records:queryRecord?key=' + apiKey, {
        method: 'POST',
        body: JSON.stringify(body),
    }).then(res => res.json());
}

レスポンス

レスポンスとして渡されるレコードには、FCP、FIDなど各指標に「Bin」と呼ばれるデータが含まれます。連続した値をある境界値で分割する前処理が行われた状態を一般的にビニング(Binning)と呼びますが、分割されたデータひとつひとつがビン(Bin)となります。

例えば、以下のようなデータを受け取ったとします。

{
    cumulative_layout_shift: {
        histogram: [
            {start: 0.0, end: 0.1, density: 0.9}, // 配列の一つ一つがBin
            {start: 0.1, end: 0.25, density: 0.05},
            {start: 0.25, density: 0.05} // 0.25以上という表現のため、endは省略されている
        ]
    }
}

この場合cumulative_layout_shift(ページロード時のガタツキ、ズレを数値化したもの)に関する以下の3つのデータが得られたことを示しています。

  • CLSの値が0.0~0.1に範囲だったユーザーの割合が全体の9割
  • CLSの値が0.1~0.25に範囲だったユーザーの割合が全体の0.05割
  • CLSの値が0.25以上だったユーザーの割合が全体の0.05割

densityの値はすべて合計すると1(100%)になるようレスポンスが返ってきます。ただし、データとしてあらわされるのは割合でしかないため、データとして集計された総ユーザー数が何人なのか、など細かいところまでは分かりません。データだけを鵜呑みにしないよう注意が必要です。

以上がAPIを使用する最低限の情報です。あとはレスポンスのデータを利用して画面に好きなように表示すればカスタムレポートが出来上がります。例えば以下のように指標ごとのグラフも手軽に作成することも可能です。

densityの値を棒グラフ化したキャプチャ

おわりに

CrUXの他にもCore Web Vitalsのスコアを手軽に計測する方法としてWeb Vitals Extensionがあります。ただし、この拡張機能で得られる数値はあくまで実行している環境(PCのスペックやネットワーク)に依存したデータ、いわゆるラボデータです。しかし、CrUXで得られるレポートはフィールドデータ、すなわち世界中でWebサイトを使用しているユーザーが実際に体感している数値に近いものです。

フィールドデータに改善の結果が反映され始めるには、長い時間がかかりますし、外部要因による意図しない影響などもあるかもしれません。新機能の開発など短期的には拡張機能を活用し、長期的にはCrUXを見ながら戦略を立てる、といったように目的に応じて必要なデータを参照するようにしましょう。