博客使用了 instantclick.js,整体上成为了单页应用,此时一般的统计工具无法使用,或是新页面不发送统计数据,或是出现单个页面多次发送统计数据的问题。
首先,说明一下,我使用了三种统计工具(其实一个就够了),包括著名的 Google Analytics,国内常用的 Baidu 统计以及自建的 matomo 统计工具。
统计原理
matomo 是一个著名的开源统计工具,这里就以它为例,简单说明一下统计的原理。
<!-- Matomo -->
<script type="text/javascript">
var _paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="//matomo.onesrc.cn/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '1']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
三个统计工具的原理类似,都是异步引入脚本,同时脚本外引入一个统计变量(通常为数组,上例中为 paq)。如果脚本先完成引入,其后才是定义统计变量,根据代码也可以看出来,此时的统计变量则直接使用定义好的 paq,否则则是先定义 paq,引入的脚本直接使用这个变量。猜想引入的统计脚本里面应该也有一句 var _paq = window._paq || []
,这样,无论二者哪个先执行,都能保证最后数据和属性的互通。
如何改进
根据上面的原理可以知道,把二者分离就可以了。但遗憾的是,分离后的代码也不能直接使用,必须将它们分为两部分,脚本的使用和脚本的引入。就像之前提到的那样,二者的顺序不影响使用,我个人习惯把脚本的引入放到后面。
Matomo
根据官方文档,大致可以这样配置。
//初始化部分,调用一次即可
window._paq = window._paq || [];
_paq.push(['setTrackerUrl', 'https://matomo.onesrc.cn/matomo.php']);
_paq.push(['setSiteId', '2']);
//统计部分,调用该部分会发送数据
_paq.push(['setCustomUrl', window.location]);
_paq.push(['setDocumentTitle', document.title]);
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
setCustomUrl 和 setDocumentTitle 必须调用,如果没有这两条而仅仅使用 trackPageView,就会导致所有发送的网站信息都是初始化页面的信息。猜测是在脚本引入时把初始页面的信息保存了下载,此后发送统计信息时直接发送这些信息,而不是发送时重新自动获取,所以每次发送统计数据前都必须重新设置该项。
Baidu
百度处理起来比较简单,提供了供单页应用使用的脚本(使用前需要在百度统计>管理>单页应用打开设置),自动监测路由变化,智能的根据 history 自动发送统计信息。
//初始化一次即可,此后无需手动调用
window._hmt = window._hmt || [];
_hmt.push(['_requirePlugin', 'UrlChangeTracker', {
shouldTrackUrlChange: function(newPath, oldPath) {
newPath = newPath.split('#')[0];
oldPath = oldPath.split('#')[0];
return newPath != oldPath;
}
}]);
Google Analytics
//初始化部分
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
//统计部分
gtag('config', 'UA-132229115-2', {
'page_path': window.location.pathname + window.location.search
});
最终结果
初始化部分:
<script data-no-instant>
//<!-- Matomo -->
window._paq = window._paq || [];
_paq.push(['setTrackerUrl', 'https://matomo.onesrc.cn/matomo.php']);
_paq.push(['setSiteId', '2']);
//<!-- End Matomo Code -->
//<!-- Baidu -->
window._hmt = window._hmt || [];
_hmt.push(['_requirePlugin', 'UrlChangeTracker', {
shouldTrackUrlChange: function(newPath, oldPath) {
newPath = newPath.split('#')[0];
oldPath = oldPath.split('#')[0];
return newPath != oldPath;
}
}]);
//<!-- End Baidu Code -->
//<!-- Global site tag (gtag.js) - Google Analytics -->
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
//<!-- End Google Analytics -->
InstantClick.on('change', function(isInitialLoad) {
_paq.push(['setCustomUrl', window.location]);
_paq.push(['setDocumentTitle', document.title]);
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
gtag('config', 'UA-132229115-2', {
'page_path': window.location.pathname + window.location.search
});
});
InstantClick.init('mousedown');
</script>
脚本引入部分:
<script type="text/javascript" async defer src="https://matomo.onesrc.cn/matomo.js" data-no-instant></script>
<script type="text/javascript" async defer src="https://hm.baidu.com/hm.js?821e8537385c0051552f4b6be4556e0c" data-no-instant>
</script>
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-132229115-2" data-no-instant></script>
同样附上改进后的截图
可以看到三个统计工具都有正确发送统计数据。
参考链接
Single-Page Application Tracking
本文由 ukuq 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Mar 12, 2020 at 10:51 pm