このブログでは、読了率を Google Tag Manager の スクロールトリガーを使って、Google Analytics 送付しています。
この実装方法だと、指定したスクロールのパーセンテージ毎にイベントが送付されるため、100% 読了になるまで何回かスクロールイベントが送付されます。
Python Google Analytics の読了率データを分析する | Monotalk でデータを分析してみたのですが、複数回取れるため集計がなかなか面倒でした。
良い方法がないか確認したところ、Demo 05. 直帰してもページの滞在時間とスクロール量をGTMで正確に計測する方法 - 清水誠メモ で beforeUnload イベントで1度だけスクロール率を測定しており、このやり方であれば集計も簡単になりそうですので、試しに実施してみました。
結果を以下に記載します。
前提
このブログは、TurboLinks を使用しています。
このため、外部リンクをクリックした場合は、beforeunload
イベントが呼び出されますが、ページ内遷移の場合は、turbolinks:visit
、onpopstate
へ実装する必要があります。
turbolinksチートシート - Qiita にTurbolinks のイベント発火タイミングが記載されていますが、turbolinks:visit
が戻る、進むで呼び出されないため、onpopstate
にも実装する必要がありました。
やったこと
以下、作業内容を記載します。
Turbolinks の初期化処理で GTMイベント pageExit
を発行するイベントリスナを設定する
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 で イベントを作成します。
スクロール距離トリガーを作成する
10%間隔で発動するスクロール距離トリガーを作成します。
今回の用途だと、これを使用するタグはないのですが、組み込み変数 Scroll Depth Threshold
を計算させるために定義します。
- 補足
JavaScriptでスクロール率を計算しているので、Google Tag Manager側でこの変数を使用することはありません。
試しに作った時の参考情報となります。
GTM データレイヤー変数を作成する
GTMイベント pageExit
送付時に設定している変数を取得するためデータレイヤー変数を作成します。
-
exitUrl
-
timeOnPage
-
scrollPercentage
ページ離脱時のイベント計測用のGAイベントタグを作成する
以下、GAイベントタグを作成しました。
transport
、 beacon
を設定すると、ページが閉じた後も非同期でイベントが送付されます。
対応していないブラウザは通常の同期イベントが送付されます。
参考
- beforeunloadについて
- beforeunload - イベントリファレンス | MDN
- Javascriptのonbeforeunloadとonunloadについて - Qiita
- User Timing API
- User Timing API: あなたの Web アプリをもっと理解するために - HTML5 Rocks
-
Navigator.sendBeacon()
- Navigator.sendBeacon() - Web API | MDN
これで、ページ離脱時に一度だけスクロールイベントが記録されるようになりました。
以上です。
コメント