FP FCP を Google Analytics に カスタム速度として設定する


ブラウザの速度指標として、Paint Timing という指標があります。
Google Analytics でもデフォルトでサイトの速度が取得できますが、おそらく Navigation Timing API の取得データを元にした値で、Paint Timing の情報は取得できません。

Paint Timing API の値を カスタム速度として設定して、Google Analytics 上で閲覧できるようにしてみました。
実施した内容を記載します。


参考


前提

実装における前提は以下になります。

  • GTM 上で、customTask を設定する
    GTM で、customTask を使い、timingTask を拡張します。
    ドキュメントには以下のような記載があり、siteSpeedSampleRate の設定に従って、カスタム速度も計測したいため、timingTask に対して設定しています。
    実際に動かしてみて気づいたのですが、Google Analytics の JavaScript は siteSpeedSampleRate の値を元に、timingTask で実行してくれるわけではなく、timingTask 内で siteSpeedSampleRate を判断して、計測を行う必要があります。

    トラッカーの siteSpeedSampleRate の設定に基づいて、サイトの速度 timing ヒットを自動的に生成します。

  • 計測の対象
    Paint Timing で測れる FP、FCP を計測対象にします。
    TTI (Time to Interactive)、CFP (Component First Paint) も計測でき、計測結果を、Google Analyticsに送付してくれるPerfume.js というライブラリも存在することがわかったのですが、GTM から上手く動かなそうだったので使用していません。


実装

GA PageView タグの設定

GTM の GA タグに siteSpeedSampleRate の値を設定します。
これは、後述しますが、CustamTask 内で、siteSpeedSampleRate を取得するためです。
変数 customTask には、以下の CustomTask 変数の JavaSctipt を設定します。

GAタグ

GA CustomTask 変数

customTask の内容は以下の通りです。
設定内容を説明します。

function() {
    function str2Num(str) {
        var b = 1;
        var charCode = 0;
        var i;
        if (str) {
          for (b = 0, i = str.length - 1; 0 <= i; i--) {
              charCode = str.charCodeAt(i);   // 16位
              // 268435455 === 1111111111111111111111111111 (28位)
              b = (b << 6 & 268435455) + charCode + (charCode << 14);
              // 266338304 === 1111111000000000000000000000 (21位 + 7位)
              var c = b & 266338304;
              b = 0 != c ? b ^ c >> 21 : b;
          }
        }
        return b
    };
    return function(model) {
        // Custom Dimensionの設定 クライアントID
        model.set('dimension8', model.get('clientId'));
        // 元のタスクの退避
        var originalTimingTask = model.get('timingTask');
        model.set('timingTask', function(timingTaskModel) {
              // 元のタスクの実行
              originalTimingTask(timingTaskModel);      
              if ('pageview' != timingTaskModel.get("hitType")) {
                  return;
              }
              var siteSpeedSampleRate = model.get('siteSpeedSampleRate');
              if (str2Num(model.get("clientId")) % 100 >= siteSpeedSampleRate) {
                  return;
              }
              // 計測対象の場合は、load イベントで、GTM にカスタムイベントを送付する
              window.addEventListener("load", function(event) {
                  if (window.performance) {
                    window.dataLayer = window.dataLayer || [];
                    var performance = window.performance;
                    var performanceEntries = performance.getEntriesByType('paint');
                    performanceEntries.forEach(function(performanceEntry, i, entries) {
                        window.dataLayer.push({
                           event: "sendTiming",
                           timingCategory: "Paint Timing",
                           timingVar: performanceEntry.name,
                           timingValue: performanceEntry.startTime,
                           timingLabel: 
                        });
                    });
                  }
              });
        });
    };
}
  • var siteSpeedSampleRate = model.get('siteSpeedSampleRate'); について
    siteSpeedSampleRate を取得します。デフォルトでは、1ですが、タグで変数を設定しないと、undefined になります。
    Google Analytics の デフォルトタスクでは デフォルト値を適用してくれますが、 1 GTM タグ上はこれを自前実装しないといけないため、デフォルト値の設定を行うようにしました。

  • str2Num 関数について
    GA的源码 analytics.js を参考に Google Analytics.js 内で実装されている関数を定義しています。

  • if (str2Num(model.get("clientId")) % 100 >= siteSpeedSampleRate) について
    GA的源码 analytics.js に記載されている、siteSpeedSampleRate を適用するか否かを判断する、関数です。アクセスの度にランダムで選択するのではなく、ユーザーの Cookie 値での判断になります。
    速度送付の対象、非対称が Cookie の値で判断されることになります。動作確認時に、この動作で少しハマりました。
    理想としては、毎回ランダムで対象を選択してもいいのかと思います。

  • カスタム速度の送付について
    Google Analytics のイベントではなく、GTM のカスタムイベントを発行して、カスタム速度を計測します。

  • model.set('dimension8', model.get('clientId')); について
    今回やりたいことは、カスタム速度送付ですが、元々の customTask の仕事として、clientId の設定を行っています。

  • window.addEventListener("load", function(event) によるイベントリスナーの設定
    GA的源码 analytics.js の実装を参考に、timingTask の設定値として送付したい内容を、load イベントのタイミングで送付するようにしています。

カスタム速度送付タグの設定

GTMカスタムイベント sendTiming に対応する、カスタム速度送付タグを作成します。
下記は、ラベルを設定していないですが、ラベルも設定したほうが、Google Analytics 上の表示は見やすいかと思います。
カスタム速度タグ


まとめ

GTM から、customTask 変数を使って、First Paint API の結果をカスタム速度として設定しました。
情報があまりなくて、思い思いの実装になりましたが、無事送付できました。
もう少し、APIが進化して TTL、SpeedIndex 等の込み入った値も送付できるようになったらそのあたりも送付するようにしようかと思います。
以上です。

コメント