アナリティクス

Next.js Speed Insightsを使用すると、さまざまなメトリクスを使ってページのパフォーマンスを分析・測定できます。

Vercelデプロイメントでは、ゼロコンフィギュレーションでReal Experience Scoreの収集を開始できます。

このドキュメントの残りの部分では、Next.js Speed Insightsが使用する組み込みのリレーヤーについて説明します。

独自の実装を構築

まず、カスタムAppコンポーネントを作成し、reportWebVitals関数を定義する必要があります:

pages/_app.js
export function reportWebVitals(metric) {
  console.log(metric)
}

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

export default MyApp

この関数は、ページ上でメトリクスの最終値が計算されるときに発火します。結果をコンソールにログ出力したり、特定のエンドポイントに送信したりするために使用できます。

関数に返されるmetricオブジェクトは次のプロパティで構成されています:

  • id: 現在のページロードコンテキストにおけるメトリクスの一意な識別子
  • name: メトリクス名
  • startTime: パフォーマンスエントリの最初に記録されたタイムスタンプ(ミリ秒単位、該当する場合)
  • value: パフォーマンスエントリの値または継続時間(ミリ秒単位)
  • label: メトリクスのタイプ(web-vitalまたはcustom

追跡されるメトリクスには2つのタイプがあります:

  • Web Vitals
  • カスタムメトリクス

Web Vitals

Web Vitalsは、ウェブページのユーザー体験を捉えることを目的とした有用なメトリクスのセットです。以下のWeb Vitalsがすべて含まれています:

web-vitalラベルを使用してこれらのメトリクスのすべての結果を処理できます:

export function reportWebVitals(metric) {
  if (metric.label === 'web-vital') {
    console.log(metric) // メトリクスオブジェクト({ id, name, startTime, value, label })がコンソールにログ出力されます
  }
}

各メトリクスを個別に処理するオプションもあります:

export function reportWebVitals(metric) {
  switch (metric.name) {
    case 'FCP':
      // FCP結果を処理
      break
    case 'LCP':
      // LCP結果を処理
      break
    case 'CLS':
      // CLS結果を処理
      break
    case 'FID':
      // FID結果を処理
      break
    case 'TTFB':
      // TTFB結果を処理
      break
    case 'INP':
      // INP結果を処理(注: INPはまだ実験的なメトリクスです)
      break
    default:
      break
  }
}

これらのメトリクスの測定には、サードパーティライブラリのweb-vitalsが使用されています。ブラウザの互換性は特定のメトリクスによって異なるため、サポートされているブラウザについてはブラウザサポートセクションを参照してください。

カスタムメトリクス

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

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

customラベルを使用してこれらのメトリクスのすべての結果を処理できます:

export function reportWebVitals(metric) {
  if (metric.label === 'custom') {
    console.log(metric) // メトリクスオブジェクト({ id, name, startTime, value, label })がコンソールにログ出力されます
  }
}

各メトリクスを個別に処理するオプションもあります:

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

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

外部システムに結果を送信

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

export function reportWebVitals(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値を使用して手動でメトリクス分布を構築できます(パーセンタイルなどを計算するため)

export function reportWebVitals({ id, name, label, value }) {
  // この例のようにGoogle Analyticsを初期化した場合は`window.gtag`を使用:
  // https://github.com/vercel/next.js/blob/canary/examples/with-google-analytics/pages/_app.js
  window.gtag('event', name, {
    event_category:
      label === 'web-vital' ? 'Web Vitals' : 'Next.js custom metric',
    value: Math.round(name === 'CLS' ? value * 1000 : value), // 値は整数でなければなりません
    event_label: id, // 現在のページロードに一意なid
    non_interaction: true, // バウンス率に影響を与えません
  })
}

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

TypeScript

TypeScriptを使用している場合、組み込みの型NextWebVitalsMetricを使用できます:

import type { AppProps, NextWebVitalsMetric } from 'next/app'

function MyApp({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />
}

export function reportWebVitals(metric: NextWebVitalsMetric) {
  console.log(metric)
}

export default MyApp
function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

export function reportWebVitals(metric) {
  console.log(metric)
}

export default MyApp