2020年5月に、Core Web Vitals という新しいパフォーマンスの指標が、Google から発表されました。
2021年から検索ランキングにも影響するようです。
Core Web Vitals の 計測ライブラリが、GoogleChrome/web-vitals: Essential metrics for a healthy site.あり、JavaScript で計測して、Google Analytics 等に記録できるので、react のアプリケーションに組み込んで計測できるか試してみました。


ライブラリで取得できる指標について

GoogleChrome/web-vitals: Essential metrics for a healthy site.取得できる指標は以下になります。

  • Cumulative Layout Shift (CLS)
    コンテンツの移動を示すスコア。
    dobule 型で値が取得できます。

  • First Contentful Paint (FCP)
    何らかのDOMコンテンツがレンダリングされた時刻。
    DOMHighResTimeStamp値が取得できます。

  • First Input Delay (FID)
    ユーザーが最初にアクセスしてから実際にイベントが発生し、イベントハンドラを呼び出されるまでの時間。
    DOMHighResTimeStamp で値が取得できます。
    First Input Delay のみを計測するライブラリもあるようです。

  • Largest Contentful Paint (LCP)
    ユーザーにとって意味のある表示状態になるまでの時間。
    DOMHighResTimeStamp で値が取得できます。
    reportAllChangesいうパラメータがあり、true指定すると、最大値の計算完了まで report を遅延させ、false指定すると計算の都度 report する動作になります。

  • Reduce server response times (TTFB)
    最初の1バイトが到着するまでの時間。
    ネットワーク帯域でのコンテンツ転送時間も含めたサーバー側の処理時間を示します。
    DOMHighResTimeStamp で値が取得できます。

Core Web Vitals の関連ライブラリ

Web Vitals に関連するライブラリを調べると以下見つかりました。


web-vitals のインストール、react アプリケーションへの組み込み

web-vitals をインストールして、react アプリケーションへの組み込みまで実施してみます。

web-vitals のインストール

npm install web-vitals

react アプリケーションへの組み込み

Correct location to call webVitals in a React SPA · Issue #41 · GoogleChrome/web-vitals実装例の記載があります。
上記を参考に、以下のような、function component を作成しました。

  • WebVitals.tsx
    sendToGTMデータをGoogle Tag Manager に送信しています。
    import { useEffect } from 'react';
    import { getCLS, getFCP, getFID, getLCP, getTTFB, Metric } from 'web-vitals';
    const { dataLayer } = window;
    
    declare global {
        interface Window {
            dataLayer: any;
        }
    }
    
    function sendToGTM({ name, delta, id }: Metric) {
        // globalなdataLayer変数がなければ生成する
        window.dataLayer = window.dataLayer || [];
        dataLayer.push({
            event: 'web-vitals',
            'eventData.category': 'Web Vitals',
            'eventData.action': name,
            // Googleアナリティクスの指標は整数である必要があるため、値は丸められる。
            // CLSの場合、精度を上げるために、最初に値に1000を掛ける。
            'eventData.value': Math.round(name === 'CLS' ? delta * 1000 : delta),
            // `id`の値は現在のページの読み込みに固有。
            //  送信時に同じページからの複数の値(CLSなど)、Googleアナリティクスは、
            // このIDでグループ化して合計を計算する(注:必要なのは `eventLabel`で、レポートのディメンションになる)。
            'eventData.label': id,
        });
    }
    
    const WebVitals = () => {
        useEffect(() => {
            getTTFB(sendToGTM);
            getFCP(sendToGTM);
            getCLS(sendToGTM);
            getFID(sendToGTM);
            getLCP(sendToGTM);
        },        []);
        return null;
    };
    export default WebVitals;
    

WebVitals.tsx の使用箇所は以下のようになります。

    return (
        <main className="mainContainer mt5rem">
            <WebVitals />
            {this.renderMetaInfo()}
            {/* this.renderEditButton() */}
            <AppPost
                title={post.title}
                slug={post.slug}
                body={post.body}
                published={post.published}
                tags={post.tags}
                category={post.category}/>
            <br/>
        </main>
    );


Google Tag Manager から、Amplitude にデータを送信する

Google Tag Manager から、GTMイベントをトリガーに、Amplitude にデータを送信します。

タグの初期設定について

Amplitude を利用する場合、初期化タグを作る必要があります。
タグの初期設定について、以下の記事にまとめていますので、ご確認ください。
Google Tag Manager で Amplitude の設定を行う | Monotalk

データレイヤー変数を作る。

Web Vitals 指標をAmplitude に送信するタグを作成します。

  • データレイヤー変数
    以下のデータレイヤー変数を作ります。
    変数名は、sendToGTM 関数で設定しているキー値に一致させます。
    • eventData.action
    • eventData.value
    • eventData.label

以下、eventData.action設定イメージになります。

Image from Gyazo

トリガー を作る

sendToGTM 関数 で設定した GTMイベントに対応するトリガーを作ります。
この記事のソースコードをそのまま流用する際は、イベント名は'web-vitals'なります。
Image from Gyazo

カスタム HTML タグを作る

作成したトリガーで、起動する カスタムHTMLタグを作ります。
Image from Gyazo

以下、カスタム HTML の内容に対する説明になります。

  • HTMLタグの内容
    データレイヤ変数を取得して、amplitude.getInstance().logEventVale 値として設定します。
    id だけだと、どの url の 計測結果なのか分からなかったので、システム変数 Page URL使って設定するようにしました。

    <script>
    // プロパティを渡してイベント送信
    amplitude.getInstance().logEvent('web-vitals', 
      {  metricnName: {{eventData.action}},  
         id: {{eventData.label}},
         value: {{eventData.value}},
         url: {{Page URL}}
     }
    );
    </script>
    

  • タグの順序付け
    タグの配信前に、Amplitude の初期化タグを配信するように設定しました。

これで、Amplitude側に、データ送信されることが確認できました。


参考

以下、参考にした記事になります。

以上です。

コメント