GA _gaq _gat的两种嵌入方式详解
GA tag支持两种嵌入方式:同步嵌入和异步嵌入,下面分别讲解一下两种不同的嵌入方式的区别和不同的应用场景
同步嵌入
同步嵌入的代码如下:
<script type=”text/javascript”>
var gaJsHost = ((“https:” == document.location.protocol) ? “https://ssl.” : “http://www.”);
document.write(unescape(“%3Cscript src=’” + gaJsHost + “google-analytics.com/ga.js’ type=’text/javascript’%3E%3C/script%3E”));
</script>
<script type=”text/javascript”>
try {
var pageTracker = _gat._getTracker(“UA-12684530-1″);
pageTracker._trackPageview();
} catch(err) {}</script>
异步嵌入
异步嵌入的代码如下:
<script type=”text/javascript”>
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX-X']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement(’script’);
ga.src = (‘https:’ == document.location.protocol ? ‘https://ssl’ : ‘http://www’) + ‘.google-analytics.com/ga.js’;
ga.setAttribute(‘async’, ‘true’);
document.documentElement.firstChild.appendChild(ga);
})();
</script>
同步的track代码调用很简单也很直白,通过_gat对象的_getTracker(“UA-12684530-1″)方法调用创建了一个pageTracker的对象,然后在trackEvent或tracsaction甚至设置customVariable的时候,直接使用pageTracker对象调用相应的方法就可以了。
如: pageTracker._trackEvent, pageTracker.——setCutomVar, pageTracker._trackPageView
但是,异步的track代码调用就不那么直白了。在解释如何进行异步的track的时候,我们需要看看借个GA对象的来龙去脉:
_gat
GA tag里面定义了一个字符串:var gaTrackerName = “_gat”, 然后通过window[gaTrackerName] = Z把_gat变成了window对象下的一个全局子对象。ok, 这个时候你看到了有趣的东西: Z. 这个是GA tag混淆后的缩写,原来Google的开发人员叫它啥,我们就不知道了,但是,我们看看Z这个对象里面都有啥吧:
一个至关重要的方法:Z._getTracker = function(i, l) {
return new Z.Tracker(i, l)
};
10个子对象。10个对象就不一一列举,但是有2个不能不看:Z.Tracker 和 Z.GlobalVariables
至此,你大致可以明了,Z这个东西就是定义了GA tag所有功能函数的一个类,而_gat就是它的一个实例了。
_gaq
同样的,GA tag里面也定义了一个变量:var ba = “_gaq”, 但是把_gaq转换成window下的一个全局对象就略显复杂一些:
首先,GA tag初始化的时候会调用一个叫na的方法:
function na() {
var i = window[ba],
l = false;
if (i && typeof i.push == “function”) {
l = i.constructor == Array;
if (!l) return
}
window[ba] = $;
l && $.push.apply($, i)
}
好吧,你看到了,window[ba] = $, 这样,_gaq就变成了$这个对象,这个对象是GA里定义的和Z同级的全局对象,让我们看看它的定义吧:
$ = {
ca: {},
_createAsyncTracker: function(i, l) {…},
_getAsyncTracker: function(i) {
i = i || “”;
var l = $.ca[i];
if (!l) {
l = new Z.Tracker;
$.ca[i] = l;
ka = true
}
return l
},
push: function() {
for (var i = arguments,
l = 0,
g = 0; g < i[x]; g++) try {
if (typeof i[g] === “function”) i[g]();
else {
var t = “”,
k = i[g][0],
p = k.lastIndexOf(“.”);
if (p > 0) {
t = O(k, 0, p);
k = O(k, p + 1)
}
var f = $._getAsyncTracker(t);
f[k].apply(f, i[g].slice(1))
}
} catch(h) {
l++
}
return l
}
};
看到了,$这个东东有3个方法:push, _getAsyncTracker,和_createAsyncTracker(这里省略了实现)。这里引出了一个对于异步tag嵌入最最重要的方法: push。所谓异步调用,无非就是把tag的加载和tag的track调用分离,那么看到push的方法实现你就明白了该如何使用这个异步调用的tag了。让我们来点实际的调用代码看看:
_gaq.push(['_setAccount', 'UA-XXXXX-X']);
_gaq.push(['_setClientInfo', false]);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setDetectFlash', false]);
_gaq.push(['_setDetectTitle', false]);
_gaq.push(['_trackPageview']);
_gaq.push(function() {
var pageTracker = _gaq._createAsyncTracker(‘UA-XXXXX-1′);
pageTracker._trackPageview();
var pageTrackerB = _gaq._createAsyncTracker(‘UA-XXXXX-2′,’b');
pageTrackerB._trackPageview();
});
GA tag没有加载的时候,_gaq是一个数组,你push进去的东西会存储起来直到tag加载。当tag加载之后,na方法将被调用:
var i = window[ba],//数组里面的值赋给了i
$.push.apply($, i)//解析并执行push到数组里的方法
前面说完了技术实现的不同,很明显,异步的tag调用要更复杂一点,那么Goolge提供异步嵌入的目的在哪呢? 异步的嵌入方式相比同步的嵌入方式主要有下面的好处:
tag 无需同步加载,不会阻塞浏览器处理整个页面DOM的过程,可以加快页面的加载速度
所有的函数都是先push进数组缓存起来,待GA 的tag完整加载后执行,将会避免因GA tag加载无法完成而导致客户端页面出错的状况发生。想象一下,在同步嵌入的方式下,如果GAtag的下载失败了(网络抖了一下或其他原因),后续的var pageTracker = _gat._getTracker(“UA-12684530-1″);必定失败,那么,如果你在其他地方调用pageTacker的方法如:pageTacker._trackEvent,必定会出现javascript错误,严重时可能导致表单无法提交或者视频广告无法播放。









