このブログでは、読了率を Google Tag Manager の スクロールトリガーを使って、Google Analytics 送付しています。
この実装方法だと、指定したスクロールのパーセンテージ毎にイベントが送付されるため、100% 読了になるまで何回かスクロールイベントが送付されます。

Python Google Analytics の読了率データを分析する | Monotalkデータを分析してみたのですが、複数回取れるため集計がなかなか面倒でした。

良い方法がないか確認したところ、Demo 05. 直帰してもページの滞在時間とスクロール量をGTMで正確に計測する方法 - 清水誠メモ beforeUnload イベントで1度だけスクロール率を測定しており、このやり方であれば集計も簡単になりそうですので、試しに実施してみました。

結果を以下に記載します。


前提

このブログは、TurboLinks を使用しています。
このため、外部リンクをクリックした場合は、beforeunload イベントが呼び出されますが、ページ内遷移の場合は、turbolinks:visitonpopstate実装する必要があります。

turbolinksチートシート - QiitaTurbolinks のイベント発火タイミングが記載されていますが、turbolinks:visit戻る、進むで呼び出されないため、onpopstate にも実装する必要がありました。


やったこと

以下、作業内容を記載します。

Turbolinks の初期化処理で以下、GTM イベントpageExit発行するイベントリスナを設定します。
Trubolinks だとページ遷移後に、スクロール率が初期化されない問題があり、Scroll Depth Threshold使った計測は諦めて、JavaScriptで必要な場合に計算するようにしました。
スクロール率の計算方法は以下 Stack Overflow の記事を参考にしました。
Cross-Browser Method to Determine Vertical Scroll Percentage in Javascript - Stack Overflow

import Turbolinks from 'turbolinks';

function currentScrollPercentage() {
    return ((document.documentElement.scrollTop + document.body.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight) * 100);
}
function pushPageExit(url) {
  performance.mark('pageExit');
  let timeOnPage = performance.measure('timeOnPage', 'pageStart', 'pageExit').duration / 1000;
  performance.clearMarks('timeOnPage');
  dataLayer.push({
    event: 'pageExit',
    exitUrl: url,
    timeOnPage: timeOnPage,
    scrollPercentage: currentScrollPercentage()
  });
}
let previousUrl;
// Turbolinksで遷移した場合の初期化処理
document.addEventListener('turbolinks:load', function(event) {
  let url = event.data.url;
  dataLayer.push({
    'event': 'turbolinks_load_pageView',
    'virtualUrl': url,
  });
  dataLayer.push({
    'event': 'optimize.activate',
    'virtualUrl': url,
  });
  previousUrl = event.data.url;
  performance.mark('pageStart');
});

document.addEventListener("turbolinks:visit", function(event){
    var url = event.data.url;
    pushPageExit(url);
})
document.addEventListener('beforeunload', function() {
    let url = location.href;
    pushPageExit(url);
});
document.addEventListener('popstate', function(e){
    if (previousUrl) {
      pushPageExit(previousUrl);
    }
});
// Turbolinks処理開始
Turbolinks.start();

各イベントの処理と、補足事項を説明します。

  • turbolinks:load
    ページ読み込み後に呼び出させるイベントリスナです。
    内部でページ読み込み後のURLの保持。
    User Timing API でページの読み込み開始をマークしています。

  • turbolinks:visit
    サイト内リンクをクリック後、ページ読み込み前に起動するイベントリスナです。
    離れるページに対するスクロール率と、ページ滞在時間を GTMイベントとして送付します。

  • beforeunload
    サイト外リンクのクリック時に呼び出されます。
    実施していることは、turbolinks:visit と変わりありません。

  • popstate
    戻るボタン、進むボタンクリック時に読み出されます。
    このケースは、turbolinks:visit は呼び出されません。
    また、URLとして遷移後のURLのみ取得可能なので、このケースで前のページのURLを送付するため、previousUrl を使用しています。

  • 補足 currentScrollPercentage関数について
    Google Tag Mamager で スクロール率を保持する組み込み変数がありますが、Turbolinks で 次ページへ遷移した後、スクロール率が 0に戻らず、100%のままになっていました。どうやらページの再読み込みが行われないため、1度 100% になってしまうと、クリアされないようでした。
    Google Tag Manager の組み込み変数で測るのを諦めて、JavaScript側で計算のために作成した処理になります。
    まだ、考慮不足な点として一度100%まで投了してスクロールを動かし、その後画面上部のリンクをクリックすると、スクロール率は100%ではなく、リンクを押した際のスクロール率が設定され、100%までスクロールした記録が残りません。
    定期的に実行して最大スクロール率を保持することで対応できそうですが、ブラウザに負荷がかかりそうですので一旦このまま様子見しようかと思います。

イベントトリガー pageExit を作成する

Google Tag Manager で イベントを作成します。
2019-09-11 4.37.03.png - Google ドライブ

スクロール距離トリガーを作成する

10%間隔で発動するスクロール距離トリガーを作成します。
2019-09-11 4.50.29.png - Google ドライブ

今回の用途だと、これを使用するタグはないのですが、組み込み変数 Scroll Depth Threshold計算させるために定義します。

  • 補足
    JavaScriptでスクロール率を計算しているので、Google Tag Manager側でこの変数を使用することはありません。
    試しに作った時の参考情報となります。

GTM データレイヤー変数を作成する

GTMイベント pageExit 送付時に設定している変数を取得するためデータレイヤー変数を作成します。

  • exitUrl
    2019-09-11 5.01.00.png - Google ドライブ

  • timeOnPage
    2019-09-11 5.01.42.png - Google ドライブ

  • scrollPercentage
    2019-09-11 19.56.43.png - Google ドライブ

ページ離脱時のイベント計測用のGAイベントタグを作成する

以下、GAイベントタグを作成しました。
2019-09-11 20.30.42.png - Google ドライブ

transport beacon設定すると、ページが閉じた後も非同期でイベントが送付されます。
対応していないブラウザは通常の同期イベントが送付されます。


参考

これで、ページ離脱時に一度だけスクロールイベントが記録されるようになりました。
以上です。

コメント