CrUX API の使用方法

Chrome UX Report API を使用して、数百万ものウェブサイトの実際のユーザー エクスペリエンス データにアクセスする方法について学びます。

Chrome UX レポート(CrUX)データセットは、Chrome ユーザーがウェブ上の人気ページに実際にアクセスしたときのユーザー エクスペリエンスを指標化したものです。クエリ可能なデータセットが BigQuery で初めてリリースされた 2017 年以降、CrUX のフィールド データは PageSpeed InsightsCrUX ダッシュボード、Search Console の Core Web Vitals レポートなどのデベロッパー ツールに統合され、デベロッパーは実際のユーザー エクスペリエンスを測定、モニタリングできるようになりました。これまで欠けていた要素は、プログラムで CrUX データに RESTful でアクセスできる無料のツールでした。このギャップを埋めるために、Google は新しい Chrome UX Report API をリリースしました。

この API は、デベロッパーが CrUX データにシンプルかつ迅速かつ包括的にアクセスできるようにすることを目的として構築されています。CrUX API は、Lighthouse パフォーマンス アナリティクスのラボデータもレポートする既存の PageSpeed Insights API とは異なり、フィールド ユーザー エクスペリエンス データのみをレポートします。CrUX API は効率化されており、ユーザー エクスペリエンス データを迅速に提供できるため、リアルタイム監査アプリケーションに最適です。

デベロッパーが最も重要な指標である Core Web Vitals にすべてアクセスできるように、CrUX API は、オリジンと URL レベルの両方で Largest Contentful Paint(LCP)、Interaction to Next Paint(INP)、Cumulative Layout Shift(CLS)を監査してモニタリングします。

では、使い方を見てみましょう。

このページで API を試す

試してみる

送信元データをクエリする

CrUX データセットのオリジンには、基盤となるすべてのページレベルのエクスペリエンスが含まれます。次の例は、コマンドラインで cURL を使用して CrUX API にリクエストし、オリジンのユーザー エクスペリエンス データを取得する方法を示しています。

API_KEY="[YOUR_API_KEY]"
curl "https://chromeuxreport.googleapis.com/v1/records:queryRecord?key=$API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{"origin": "https://web.dev"}'

curl コマンドは次の 3 つの部分で構成されています。

  1. 呼び出し元の非公開 API キーを含む、API の URL エンドポイント。
  2. Content-Type: application/json ヘッダー。リクエスト本文に JSON が含まれていることを示します。
  3. https://web.dev オリジンを指定する JSON エンコードされたリクエスト本文

JavaScript で同じことをするには、CrUXApiUtil ユーティリティを使用します。このユーティリティは、API 呼び出しを行い、デコードされたレスポンスを返します(履歴やバッチのサポートなど、その他の機能については、GitHub のバリエーションもご覧ください)。

const CrUXApiUtil = {};
// Get your CrUX API key at https://goo.gle/crux-api-key.
CrUXApiUtil.API_KEY = '[YOUR_API_KEY]';
CrUXApiUtil.API_ENDPOINT = `https://chromeuxreport.googleapis.com/v1/records:queryRecord?key=${CrUXApiUtil.API_KEY}`;
CrUXApiUtil.query = function (requestBody) {
  if (CrUXApiUtil.API_KEY == '[YOUR_API_KEY]') {
    throw 'Replace "YOUR_API_KEY" with your private CrUX API key. Get a key at https://goo.gle/crux-api-key.';
  }
  return fetch(CrUXApiUtil.API_ENDPOINT, {
    method: 'POST',
    body: JSON.stringify(requestBody)
  }).then(response => response.json()).then(response => {
    if (response.error) {
      return Promise.reject(response);
    }
    return response;
  });
};

[YOUR_API_KEY]に置き換えます。次に、CrUXApiUtil.query 関数を呼び出して、リクエスト本文オブジェクトを渡します。

CrUXApiUtil.query({
  origin: 'https://web.dev'
}).then(response => {
  console.log(response);
}).catch(response => {
  console.error(response);
});

このオリジンにデータが存在する場合、API レスポンスは、ユーザー エクスペリエンスの分布を表す指標を含む JSON エンコードされたオブジェクトです。分布指標は、ヒストグラム バケットとパーセンタイルです。

{
  "record": {
    "key": {
      "origin": "https://web.dev"
    },
    "metrics": {
      "largest_contentful_paint": {
        "histogram": [
          {
            "start": 0,
            "end": 2500,
            "density": 0.7925068547983514
          },
          {
            "start": 2500,
            "end": 4000,
            "density": 0.1317422195536863
          },
          {
            "start": 4000,
            "density": 0.07575092564795324
          }
        ],
        "percentiles": {
          "p75": 2216
        }
      },
      // ...
    }
  }
}

histogram オブジェクトの start プロパティと end プロパティは、指定された指標でユーザーが目にする値の範囲を表します。density プロパティは、その範囲内のユーザー エクスペリエンスの割合を表します。この例では、すべての web.dev ページの LCP ユーザー エクスペリエンスの 79% が 2,500 ミリ秒未満です。これは「良好」な LCP のしきい値です。percentiles.p75 の値は、この分布内のユーザー エクスペリエンスの 75% が 2,216 ミリ秒未満であることを意味します。レスポンス構造の詳細については、レスポンス本文のドキュメントをご覧ください。

エラー

CrUX API に特定のオリジンのデータがない場合、JSON エンコードされたエラー メッセージが返されます。

{
  "error": {
    "code": 404,
    "message": "chrome ux report data not found",
    "status": "NOT_FOUND"
  }
}

このエラーをデバッグするには、まず、リクエストされたオリジンが一般公開されていることを確認します。これは、ブラウザのアドレスバーにオリジンを入力し、リダイレクト後の最終ページ URL と比較することでテストできます。一般的な問題には、サブドメインの不要な追加や省略、間違った HTTP プロトコルの使用などがあります。

エラー
{"origin": "http://www.web.dev"}

このオリジンには、http:// プロトコルと www. サブドメインが誤って含まれています。

成功
{"origin": "https://web.dev"}

このオリジンは一般公開されています。

リクエストされた送信元がナビゲート可能なバージョンである場合、送信元のサンプル数が不十分な場合にも、このエラーが発生することがあります。データセットに含まれるすべてのオリジンと URL には、個々のユーザーを匿名化するために十分な数の試聴が含まれている必要があります。また、オリジンと URL は一般公開でインデックス登録できる必要があります。ウェブサイトがデータセットに含まれる仕組みについて詳しくは、CrUX の方法論をご覧ください。

URL データをクエリする

オリジンの全体的なユーザー エクスペリエンスについて CrUX API をクエリする方法について説明しました。結果を特定のページに制限するには、url リクエスト パラメータを使用します。

API_KEY="[YOUR_API_KEY]"
curl "https://chromeuxreport.googleapis.com/v1/records:queryRecord?key=$API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{"url": "https://web.dev/fast/"}'

この cURL コマンドはオリジンの例に似ていますが、リクエスト本文で url パラメータを使用して検索するページを指定しています。

JavaScript で CrUX API から URL データをクエリするには、リクエスト本文の url パラメータを使用して CrUXApiUtil.query 関数を呼び出します。

CrUXApiUtil.query({
  url: 'https://web.dev/fast/'
}).then(response => {
  console.log(response);
}).catch(response => {
  console.error(response);
});

この URL のデータが CrUX データセットに存在する場合、API は JSON エンコードされたレスポンスを返します。次に例を示します。

{
  "record": {
    "key": {
      "url": "https://web.dev/fast/"
    },
    "metrics": {
      "largest_contentful_paint": {
        "histogram": [
          {
            "start": 0,
            "end": 2500,
            "density": 0.8477304539092148
          },
          {
            "start": 2500,
            "end": 4000,
            "density": 0.08988202359528057
          },
          {
            "start": 4000,
            "density": 0.062387522495501155
          }
        ],
        "percentiles": {
          "p75": 1947
        }
      },
      // ...
    }
  }
}

結果は、https://web.dev/fast/ の 85% で LCP が「良好」であり、75 パーセンタイルが 1,947 ミリ秒であることを示し、オリジン全体の分布よりもわずかに優れています。

URL の正規化

CrUX API は、リクエストされた URL を正規化して、既知の URL のリストに一致させます。たとえば、URL https://web.dev/fast/#measure-performance-in-the-field をクエリすると、正規化により https://web.dev/fast/ のデータが返されます。この場合、レスポンスには urlNormalizationDetails オブジェクトが含まれます。

{
  "record": {
    "key": {
      "url": "https://web.dev/fast/"
    },
    "metrics": { ... }
  },
  "urlNormalizationDetails": {
    "normalizedUrl": "https://web.dev/fast/",
    "originalUrl": "https://web.dev/fast/#measure-performance-in-the-field"
  }
}

URL の正規化について詳しくは、CrUX のドキュメントをご覧ください。

フォーム ファクタ別のクエリ

ユーザー エクスペリエンスは、ウェブサイトの最適化、ネットワークの状態、ユーザーのデバイスによって大きく異なる場合があります。これらの違いを詳しく把握するには、CrUX API の formFactor ディメンションを使用して、オリジンと URL のパフォーマンスをドリルダウンします。

この API は、DESKTOPPHONETABLET の 3 つの明示的なフォーム ファクタ値をサポートしています。オリジンまたは URL に加えて、リクエスト本文で次のいずれかの値を指定して、結果を特定のユーザー エクスペリエンスに限定します。この例では、cURL を使用してフォーム ファクタで API をクエリする方法を示します。

API_KEY="[YOUR_API_KEY]"
curl "https://chromeuxreport.googleapis.com/v1/records:queryRecord?key=$API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{"url": "https://web.dev/fast/", "formFactor": "PHONE"}'

JavaScript を使用して CrUX API にフォーム ファクタ固有のデータをクエリするには、リクエスト本文の url パラメータと formFactor パラメータを使用して CrUXApiUtil.query 関数を呼び出します。

CrUXApiUtil.query({
  url: 'https://web.dev/fast/',
  formFactor: 'PHONE'
}).then(response => {
  console.log(response);
}).catch(response => {
  console.error(response);
});

formFactor パラメータを省略すると、すべてのフォーム ファクタのデータがまとめてリクエストされます。

{
  "record": {
    "key": {
      "url": "https://web.dev/fast/",
      "formFactor": "PHONE"
    },
    "metrics": {
      "largest_contentful_paint": {
        "histogram": [
          {
            "start": 0,
            "end": 2500,
            "density": 0.778631284916204
          },
          {
            "start": 2500,
            "end": 4000,
            "density": 0.13943202979515887
          },
          {
            "start": 4000,
            "density": 0.08193668528864119
          }
        ],
        "percentiles": {
          "p75": 2366
        }
      },
    // ...
    }
  }
}

レスポンスの key フィールドは、formFactor リクエスト構成をエコーバックして、スマートフォンのエクスペリエンスのみが含まれていることを確認します。

前のセクションで説明したように、このページのユーザー エクスペリエンスの 85% で LCP は「良好」でした。スマートフォン固有のエクスペリエンスと比較すると、78% のみが「良い」と評価されています。スマートフォンでの 75 パーセンタイルは、1,947 ミリ秒から 2,366 ミリ秒に増加し、遅くなっています。フォーム ファクタでセグメント化すると、ユーザー エクスペリエンスの差異がより顕著になる可能性があります。

Core Web Vitals のパフォーマンスを評価する

Core Web Vitals プログラムでは、ユーザー エクスペリエンスまたはエクスペリエンスの分布を「良好」と見なせるかどうかを判断するのに役立つ目標が定義されています。次の例では、CrUX API と CrUXApiUtil.query 関数を使用して、ウェブページの Core Web Vitals 指標(LCP、INP、CLS)の分布が「良好」かどうかを評価します。

CrUXApiUtil.query({
  url: 'https://web.dev/fast/'
}).then(response => {
  assessCoreWebVitals(response);
}).catch(response => {
  console.error(response);
});

function assessCoreWebVitals(response) {
  // See https://web.dev/articles/vitals/#core-web-vitals.
  const CORE_WEB_VITALS = [
    'largest_contentful_paint',
    'interaction_to_next_paint',
    'cumulative_layout_shift'
  ];
  CORE_WEB_VITALS.forEach(metric => {
    const data = response.record.metrics[metric];
    if (!data) {
      console.log('No data for', metric);
      return;
    }
    const p75 = data.percentiles.p75;
    const threshold = data.histogram[0].end;
    // A Core Web Vitals metric passes the assessment if
    // its 75th percentile is under the "good" threshold.
    const passes = p75 < threshold;
    console.log(`The 75th percentile (${p75}) of ${metric} ` +
        `${passes ? 'passes' : 'does not pass'} ` +
        `the Core Web Vitals "good" threshold (${threshold}).`)
  });
}

結果は、このページが 3 つの指標すべてでウェブに関する主な指標のテストに合格していることを示しています。

The 75th percentile (1973) of largest_contentful_paint passes the Core Web Vitals "good" threshold (2500).
The 75th percentile (20) of interaction_to_next_paint passes the Core Web Vitals "good" threshold (200).
The 75th percentile (0.05) of cumulative_layout_shift passes the Core Web Vitals "good" threshold (0.10).

CrUX のデータと、API の結果を自動的にモニタリングする方法とを組み合わせることで、実際のユーザー エクスペリエンスの高速化高速化の維持を実現できます。Core Web Vitals とその測定方法について詳しくは、ウェブに関する主な指標Core Web Vitals を測定するツールをご覧ください。

次のステップ

CrUX API の初期バージョンに含まれる機能は、CrUX で得られる分析情報のほんの一部にすぎません。BigQuery の CrUX データセットのユーザーは、次のような高度な機能に精通している可能性があります。

  • その他の指標
    • first_paint
    • dom_content_loaded
    • onload
    • time_to_first_byte
    • notification_permissions
  • その他のディメンション
    • month
    • country
    • effective connection type(ECT)
  • 粒度の細分化
    • 詳細なヒストグラム
    • その他のパーセンタイル

公式の CrUX API ドキュメントで、API キーを取得し、その他のサンプル アプリケーションを確認してください。ぜひお試しください。ご質問やフィードバックがございましたら、CrUX ディスカッション フォーラムからお寄せください。CrUX API に関する最新情報については、CrUX のお知らせフォーラムに登録するか、Twitter で @ChromeUXReport をフォローしてください。