useReportWebVitals

useReportWebVitals フックを使用すると、Core Web Vitals を報告でき、アナリティクスサービスと組み合わせて使用できます。

pages/_app.js
import { useReportWebVitals } from 'next/web-vitals'

function MyApp({ Component, pageProps }) {
  useReportWebVitals((metric) => {
    console.log(metric)
  })

  return <Component {...pageProps} />
}

useReportWebVitals

フックの引数として渡される metric オブジェクトは、以下のプロパティで構成されています:

  • id: 現在のページロードコンテキストにおけるメトリックの一意な識別子
  • name: パフォーマンスメトリックの名前。Web Vitals メトリック(TTFB、FCP、LCP、FID、CLS)の名前など、ウェブアプリケーション固有の値が含まれます。
  • delta: メトリックの現在値と前回値の差。通常はミリ秒単位で、時間経過に伴うメトリック値の変化を表します。
  • entries: メトリックに関連する Performance Entries の配列。これらのエントリは、メトリックに関連するパフォーマンスイベントの詳細情報を提供します。
  • navigationType: メトリック収集をトリガーした ナビゲーションタイプ を示します。"navigate""reload""back_forward""prerender" などの値が可能です。
  • rating: メトリック値の定性的評価で、パフォーマンスの評価を提供します。"good""needs-improvement""poor" などの値が可能です。評価は通常、許容可能または最適ではないパフォーマンスを示す事前定義された閾値とメトリック値を比較して決定されます。
  • value: パフォーマンスエントリの実際の値または期間(通常はミリ秒単位)。この値は、メトリックが追跡するパフォーマンス側面の定量的測定を提供します。値のソースは測定対象の特定のメトリックによって異なり、さまざまな Performance API から取得できます。

Web Vitals

Web Vitals は、ウェブページのユーザーエクスペリエンスを把握するための有用なメトリックセットです。以下の Web Vitals がすべて含まれます:

これらのメトリックの結果はすべて name プロパティを使用して処理できます。

pages/_app.js
import { useReportWebVitals } from 'next/web-vitals'

function MyApp({ Component, pageProps }) {
  useReportWebVitals((metric) => {
    switch (metric.name) {
      case 'FCP': {
        // FCP 結果の処理
      }
      case 'LCP': {
        // LCP 結果の処理
      }
      // ...
    }
  })

  return <Component {...pageProps} />
}

カスタムメトリック

上記のコアメトリックに加えて、ページのハイドレーションとレンダリングにかかる時間を測定する追加のカスタムメトリックがあります:

  • Next.js-hydration: ページのハイドレーション開始から終了までの時間(ミリ秒単位)
  • Next.js-route-change-to-render: ルート変更後のページレンダリング開始までの時間(ミリ秒単位)
  • Next.js-render: ルート変更後のページレンダリング終了までの時間(ミリ秒単位)

これらのメトリックの結果は個別に処理できます:

pages/_app.js
import { useReportWebVitals } from 'next/web-vitals'

function MyApp({ Component, pageProps }) {
  useReportWebVitals((metric) => {
    switch (metric.name) {
      case 'Next.js-hydration':
        // ハイドレーション結果の処理
        break
      case 'Next.js-route-change-to-render':
        // ルート変更からレンダリングまでの結果処理
        break
      case 'Next.js-render':
        // レンダリング結果の処理
        break
      default:
        break
    }
  })

  return <Component {...pageProps} />
}

これらのメトリックは、User Timing API をサポートするすべてのブラウザで動作します。

Vercel での使用

Vercel Speed Insights は Vercel デプロイで自動的に設定され、useReportWebVitals の使用は不要です。このフックはローカル開発時や別のアナリティクスサービスを使用している場合に有用です。

外部システムへの結果送信

結果を任意のエンドポイントに送信し、サイトの実際のユーザーパフォーマンスを測定・追跡できます。例:

useReportWebVitals((metric) => {
  const body = JSON.stringify(metric)
  const url = 'https://example.com/analytics'

  // 利用可能な場合は `navigator.sendBeacon()` を使用し、フォールバックとして `fetch()` を使用
  if (navigator.sendBeacon) {
    navigator.sendBeacon(url, body)
  } else {
    fetch(url, { body, method: 'POST', keepalive: true })
  }
})

豆知識: Google Analytics を使用する場合、id 値を利用して手動でメトリック分布を構築できます(パーセンタイル計算など)。

useReportWebVitals(metric => {
  // この例のように Google Analytics を初期化した場合は `window.gtag` を使用:
  // https://github.com/vercel/next.js/blob/canary/examples/with-google-analytics/pages/_app.js
  window.gtag('event', metric.name, {
    value: Math.round(metric.name === 'CLS' ? metric.value * 1000 : metric.value), // 値は整数である必要あり
    event_label: metric.id, // 現在のページロードに一意な id
    non_interaction: true, // バウンス率への影響を回避
  });
}

Google Analytics への結果送信 について詳しく読む。