console.trace();

旬なものから枯れたテクノロジーまで

Google Tag ManagerとGoogle Analytics  たぶんその1

つい先日出ましたね。GoogleTagManager(=以下GTM)

最近仕事て使う機会が増えてきたので自分用メモがてらちょこちょことまとめて行こうと思いますよっと。

概要

ざっくりどんなものかを説明すると、

管理画面にアクセス出来る人がタグマネージャを使用したいドメインを設定し、コンテナと呼ばれるタグの集合体を管理する箱を作成。 発行されるタグを対象ドメインに貼り付け、独自のタグや独自のスクリプトを記述したタグを設定し、 公開ボタンをぽちっとするだけで3で作成したコンテナがサイトに埋め込まれる。

これだけでサイトがいじれてしまうという優れもの。 メリットデメリットは他の人も触れているみたいなので、 今回フォーカスしたいのはイベントについて。

タグ読み込みとイベントのタイミング

ご存知の通り、GTMはタグの読み込まれる順番を指定できない。これが非常に厄介。 けども、任意のタイミングで何かを行うscriptを記述したい場合、適切なタイミングで実行する方法が用意されている。

未知との遭遇にハマったのでリファレンス見たり、内部読んでみて自分なりに調べてみた。(間違っていたら指摘いただけると幸いです)

  • gtm.js

    • gtm.jsがscriptタグでdocumentappendされたタイミングでのタグの実行

    • DOMの状態はページや環境によるのでここでDOMを使っての操作は行わないほうが無難

  • gtm.dom

    • DOMContentLoadedのタイミングでのタグの実行

    • DOMが準備されているので要素を操作する際に最適

  • gtm.load

    • window.onloadのタイミングでのタグの実行

    • ブラウザのレンダリングが完了している段階なので操作は出来るだけ少なめにしたいところ

と、3つのイベントのタイミングを用意しているみたい。 ただ、何も指定しなかった場合は具体的にどのタイミングで読み込まれるのだろう?という疑問点もあるので後々調べて追記予定。

4/16追記

どうやら上で書いたイベントのタイミングは大嘘だったようだ。。。 上で書いたのは今自分が触っているページにのみ起こる事象で、ページによってだいぶかわってくるみたい。

で、さっそくテストケースを用意して試してみた。


<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>gtm</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
</head>

<body>
<noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-XXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<script>
window.addEventListener('DOMContentLoaded', function () {
    console.log('window.DOMContentLoaded', new Date().getTime(), document.getElementById('elem'));
});
document.addEventListener('DOMContentLoaded', function () {
    console.log('document.DOMContentLoaded', new Date().getTime(), document.getElementById('elem'));
});

$(function () {
    console.log('$(document).ready()', new Date().getTime(), document.getElementById('elem'));
});


window.addEventListener('load', function () {
    console.log('onload', new Date().getTime(), document.getElementById('elem'));
});

(function(w,d,s,l,i){

    w[l]= w[l] || [];
    w[l].push({
        'gtm.start': new Date().getTime(),
        event:'gtm.js'
    });

    var f=d.getElementsByTagName(s)[0],
        j=d.createElement(s),
        dl= l!='dataLayer' ? '&l=' + l : '' ;
        j.async=true;
        j.src = '//www.googletagmanager.com/gtm.js?id=' + i + dl;

    console.log(w[l], new Date().getTime(), document.getElementById('elem'));

    f.parentNode.insertBefore(j,f);

})(window, document, 'script', 'dataLayer', 'GTM-XXXX');

</script>

<a id="elem" href="#">test</a>
<div></div>
<div></div>
.
.
.
<!-- divの繰り返し -->
.
.
<div></div>
<div></div>
</body>
</html>

GTM上で前述の3つの各タイミング + 無指定(=ここではunknownと表示)でnew Date().getTime()でミリ秒を取得し、 console.logを実行してどういったタイミングでGTMのイベントが行われているのかを厳密に調べてみた。

Chrome

f:id:yotanote123:20130416212709j:plain

IE9

f:id:yotanote123:20130416213147j:plain

環境によってかなりの差があることがわかる。 このあたりはブラウザのAsynchronous Loadingが密接に関係しているのだろう。 でも、結果を見て思うのはgtm.domでDOMは確実に用意されているので、DOMが必要な処理の際はgtm.domで実行するのがいいのかも。

参考 CSS/JavaScriptのAsynchronous Loadingをめぐる熱い論議

上記ソースコード<!-- divの繰り返し -->の部分にリソースのロードを挟んでいたらまた挙動が変わってくるのだろう。 またそっちも後日テスト予定。

GoogleAnalyticsとの併用について

やっと本題です。

GTM使うとなると更に組み合わせたくなるのがGoogleAnalytics(=以下GA)。 これで現在推奨されている第三世代のコードを掛け合わせると、またまた厄介なことになる。

コードを見てみよう。

  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-XXXXX-X']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();

そう、async属性を指定している

さっき紹介したGTMの3つのタイミング + ga.jsのロード時間も考慮しなくちゃならない。 何が怖いって、さっきの3つのタイミングでga.jsが確実にロードしている保証なんてどこにもないのである

カスタム変数の値を見て、その値を元にページ内のとあるa要素を取得してそこにトラックイベントを飛ばすイベントハンドラをセットしたいなんて場合、 DOMContentLoadedのタイミングとga.jsのロードのタイミングが等価である保証は絶対にない。

まとめ

  • gtm.jsとga.jsを併用した場合、 windowまたはdocumentのロード状態とga.jsのロードのタイミングが等価である保証は絶対にないので、 GTMの設定は適切なタイミングを管理画面から設定して、ga.jsの読み込みを確認しながらscript書こう

  • ページのnodeの数や閲覧ブラウザや通信状況などによってga.jsのロードタイミングもかわってくるよ

  • 解析士が開発しないなんて言う時代は終わったと声を大にして言いたい(自分は解析士じゃないので戯言)

おわり