簡易にGoogleAnalyticsを使用する
本記事の対象者
- 少しでもサイトを高速化したい人
- Google Tag Manager(gtag.js)を使いたくない人
- Google Analytics(analytics.js)のサンプルコードが欲しい人
タグマネージャーを使用しない理由
タグマネージャー(gtag.js
)を使用しているページを解析するとanalytics.js
を読み込んでいなくても、analytics.js
が読み込まれています。このことから、gtag.js
は、analytics.js
の機能をラップしているのだと考えられます。そのため、最小環境でGoogle Analyticsを使用するのであれば、analytics.js
を使用することになります。そのほうが、ページの読み込みファイル数を削減でき、サイトが高速化できます。
解析内容
- 表示イベントを収集する
- 404ページの表示
- 外部サイト(別ホスト)での表示
- Google翻訳とか?
- クリックイベントを収集する
- 内部リンク
- 外部リンク
- ページ内リンク
- JavaScript実行
- ただし、動的に追加したaタグは対象外
- 読了率を収集する
- ページ全体を画面内に表示した範囲(0-100)
※ページの読み込み速度は、コメントアウトで記載
Analytics標準の読込み速度で十分と判断したため
コード:定義部
定義部<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXXXXXX-X', 'auto');
ga('send', 'pageview');
</script>
※<head>
内部に追加する
※UA-XXXXXXXXX-X
(トラッキングID)要修正
コード:処理部
処理部(function(doc, win) {
// 子要素判定
const isChildElement = function(parent, child) {
if (parent) {
for (; child; child=child.parentElement) {
if (parent == child) {
return true;
}
}
}
return false;
};
// 要素のパス作成
const createTagPath = function(element) {
let array = [];
for (; element; element=element.parentElement) {
let text = element.tagName || '';
if (element.id) {
text = '#'+element.id;
} else {
if (element.className) {
text += '.'+element.className.replace(' ', '.');
}
if (element.name) {
text += '[name="'+element.name+'"]';
}
}
array.push(text);
if (element.id) { break; }
}
return array.reverse().join(' ');
};
// イベント送信
const sendEvent = function(category, action, label, value) {
ga('send', 'event', category, action, label, value, {nonInteraction:true});
};
// ページ表示を設定
function initView() {
// 特定のページ表示イベント
// TODO: 404ページ判定変更
if (doc.getElementById('post-404')) {
sendEvent('view', '404', location.href, 1);
}
// TODO: ドメイン変更
if (location.host != 'www.bugbugnow.net') {
sendEvent('view', 'unknown', location.href, 1);
}
}
// クリックイベントを設定
function initClick() {
function onClick(e) {
let action = 'etc';
let label = e.target.href;
let m = e.target.href.match(/^https?:\/\/([^\/]+)/);
if (m && m[1] == location.host) {
action = 'inbound';
} else if (m) {
action = 'outbound';
} else if (e.target.href.substr(0, 1) == '#'){
action = 'target';
} else if (e.target.href.substr(0, 18) == 'javascript:void(0)'){
action = 'js';
label = location.href+'@'+createTagPath(a);
} else {
action = 'etc';
label = location.href+'@'+createTagPath(a);
}
ga('send', 'event', category, action, label, value);
}
let ankers = doc.getElementsByTagName('a');
for (let i=0; i<ankers.length; i++) {
ankers[i].addEventListener('click', onClick);
}
}
// 読了率
function initScroll() {
let arrival = 0;
function onScroll() {
const y = win.pageYOffset;
const ch = doc.documentElement.clientHeight;
const dh = doc.documentElement.scrollHeight;
const w = dh - ch;
const arr = y / w;
if (arrival < arr) {
arrival = arr;
}
}
let timer = null;
win.addEventListener('scroll', function() {
// 高頻度呼び出し対策
clearTimeout(timer);
timer = setTimeout(onScroll, 300);
});
win.addEventListener('beforeunload', function() {
onScroll();
const arr = Math.floor(arrival * 100);
const label = (Math.ceil(arr / 20) * 20)+'%';
sendEvent('scroll', 'page', label, arr);
});
}
function main() {
initView();
initClick();
initScroll();
}
//main();
win.addEventListener('DOMContentLoaded', main);
})(document, window);
※</body>
の直前に配置する
※TODO:
箇所を要修正