正确使用 Google 统计代码的异步加载特性

写这篇文章是因为我比较后知后觉,同时还粗心大意没有仔细去看 Google 的文档(异步跟踪使用指南)。所以当我知道 Google Analytics 统计代码开始采取异步加载的方式来提高用户体验之后,就简单得把代码更新了,而没有做任何的思考,哪怕只是稍稍动点儿脑筋。所以把这篇文章献给跟我有相似情况的朋友。

一、背景介绍

Google 早在2009年12月就发布了这一新的改进,我是大约1个月前才知道的。然后不假思索的就简单的将原来的代码(放在了页尾)去掉,而将新的代码放在了页头。

可是我后来发现这么做并没有达到目的:提高 GA 统计准确性的同时,不阻碍网页的加载和渲染速度!

因为在页头加载 JavaScript 代码会使得网页必须在 JS 代码完全下载完成之后才开始进行页面的渲染,也就是显示给用户看(详情请阅读优化WordPress中JavaScript加载位置)。所以以前我将统计代码放在页尾,然后这次我又将代码全部放在了页头。但是这么做并没有正确理解 Google 这么做提供异步加载特性的含义,因为我没有仔细看 Google 对新代码的说明。

对于 Google 网站统计的这个新特性,很多网站都有介绍,比如著名的月光博客(但是这里没有明确的指出该怎么用,可能作者觉得大家都知道怎么正确使用),还有另外一个在我搜索的时候排名很靠前的网址兽(这里比较搞笑,介绍的方法根本就是误导,都不知道他写的是什么意思)。

下面先说明异步加载的真正含义,然后再说明该怎么用。

二、什么是异步加载?

非常感谢网友 driftcloudy 热心提出建议!

鉴于网友 driftcloudy 对我关于“异步加载”的解释的质疑(见文后评论),而我也没有时间,实际上也没有必要,去深究还是忍不住好奇深究了一下。不过还是请大家对这一部分姑妄看之。

另,已经对一些表述上存在混淆的地方做了修改,当然,还是基于我自己的认识。

异步加载当然就指的是非同步加载。通常浏览器加载 javascript 文件需要按照顺序,等待一个下载完毕才去接着下载后一个。很明显,这样会比较“耽误时间”。异步加载就解决了这个问题。让你可以在加载网站上本地 js 文件的同时下载 Google 的 GA 代码。

当然,即便是同时下载,也需要占用一定的处理时间。所以,对于 Google 的这套统计代码来讲,我们可以让就是开始记录统计数据和对这些统计数据进行处理(需要 Google 统计代码,如 ga.js,来执行这些操作,比如上传到 Google 服务器)可以不同步的分别进行。也就是我们将 GA 代码中的记录部分放到页头,而处理部分放到页面底部,使得记录可以早些开始,而对数据的处理则等到统计代码 ga.js 下载完成,也就是页面显示完成后再开始,这样就可以达到提高用户体验的目的。

当然,网速很快的话这个差别并不明显。但是如果你找个访问 Google 服务器很慢的地方来打开一个网站,如果在下载 Google 统计程序的这里卡住了,你就能看到效果了。所以我们希望把下载统计程序(对 Google 网站统计来说就是 ga.js 那个 js 文件)放在网页的末尾,使之不影响前面内容的显示。

三、如何正确使用 GA 的异步加载特性

下面我们先来看看从 Google 网站统计那里直接得到的统计代码是什么样子(这里是我的,很简单,我只需要统计页面访问量):

<script type=”text/javascript”>
var _gaq = _gaq || [];
_gaq.push([‘_setAccount’, ‘UA-xxxxxxxx-y’]);
_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);
})();
</script>

上面的代码中,红色部分是开始记录的变量;蓝色部分是加载统计程序并对前面的记录进行处理;绿色部分是在网页中放置 JavaScript 代码所使用的标记。

如果你把整个上面的全部代码都放置在一起不做任何改变,那么就跟原来的非异步加载方法效果一样差不多,因为还是需要在页面头部处理 ga.js 代码(虽然可以在下载别的文件的同时下载 GA 代码);要真正利用异步加载功能,就必须可以对上面的代码在放置位置上进行处理。

处理的方法就是将上面的代码分成 2 部分,红色部分用绿色部分包裹之后放在页面的顶部,比如 </head> 标记之前;而蓝色部分同样用绿色部分包裹,放在页面的尾部,比如 </body> 标记之前。

分离之后的代码如下:

记录部分:

<script type=”text/javascript”>

var _gaq = _gaq || [];
_gaq.push([‘_setAccount’, ‘UA-xxxxxxxx-y’]);
_gaq.push([‘_trackPageview’]);

</script>

下载处理程序部分:

<script type=”text/javascript”>

(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);
})();

</script>

其实 Google 的指南上分割代码段那一块举了个例子,但是它也没有明说让你将这两块分别放置(因为例子就已经暗示了这个问题了)。另外,可能是因为这么做也会存在一个问题。那就是,别人可能没等 ga.js 下载处理完就关闭了网页,那么开始记录的数据就无效了,因为没有机会被处理。但是再想一想就会发现其实无所谓,反正是比原来那种方式好很多。

四、博主推荐

当然,很多人需要的只是个结果,“你直接告诉我怎么做最好就行了”。可是我也不是这方面的权威,只能给大家推荐一下我感觉最好的方式了。

实际上,Google 暗示的方法就非常好,直接将 2 段代码都放在页面靠前的位置,比如 </head> 标记之前。虽然需要在页面加载的初期就开始处理 GA 代码,可是现在的机器基本上都是性能过剩,处理这么一点儿代码不算什么,而且浏览器也都经过优化。说到这里,还提醒各位读者,尽量用新版本的浏览器吧。这样一来就可以,

  1. 避免没有统计到用户在页面加载完就关闭页面的那一部分访问量(似乎没什么用吧?);
  2. 利用同时下载来节省总的代码下载时间。

如果你觉得有必要,还可以使用 2 个网站统计号码(如 UA-xxxxxxxx-1 和 UA-xxxxxxxx-2)一前一后作为比较。(注意,如果这么做的话,后一统计代码片段需要上面提到的完整的 2 个部分。)

五、后记

如果你对上面的说明还不甚了解,请参考开头让大家参考的我的那篇文章。当然,如果还是有问题,欢迎在下面留言。

我一直觉得国人写的东西让人看起来很费劲(错的就不说了,另当别论)。比如大学教材,看国人的教材,通常是翻了很多参考书之后还不甚明了;但是看国外的大学教材,不但语言很明晰,就连例子都举得恰到好处。相信有过这种经历的人都会赞同我这个观点。然后网络文章呢,国人就是一大抄,很多干脆就是执行拿来主义,而自己写的一些技术文章吧,还有很多类似于国内的大学教材的。他们似乎自己并没有实践或者求证自己写的东西,比如我在“同行图片与文本居中对齐的CSS”一文中提到的。

所以我养成了一个使用 google.com 来直接查找英文文章的习惯。

如果本文有什么说得不对的地方,还请不吝指出!©

本文发表于水景一页。永久链接:<https://cnzhx.net/blog/set-asynchronous-ga-tracking-code-right/>。转载请保留此信息及相应链接。

21 条关于 “正确使用 Google 统计代码的异步加载特性” 的评论

  1. “异步加载,分两部分”比 全部放在footer效果要好吗? 博主使用效果如何?
    PS:据说自己托管统计代码,效果最好。只是 统计代码不及时更新会失效。
    PS:确实,有些家伙喜欢装深沉,不懂装懂,把文章弄得很sophisticated,显得自己很博学,其实是在装B。哈哈哈。

    • 理论上来说两种方法各有各的侧重点,但如果从页面加载速度上来说,文中介绍的肯定效果要好。
      我是觉得用国外的服务器,网速是很大的瓶颈,自己托管不如用 Google 的资源快。

  2. 对了!上面那一行社会分享图标是如何实现的?插件?还是 自建的JS?教教我,3Q

  3. 逛了那么多个blog,看了那么多种使用方法,这种最易懂啦。先体验一下速度

  4. “对于 Google 的这套统计代码来讲,就是开始记录统计数据和对这些统计数据进行处理(比如上传到 Google 服务器)可以不同步的进行。也就是记录可以早些开始,而处理等到页面显示完成后再开始,这样就可以提高用户体验。”
    LZ讲错了…这不是GA所谓的异步加载带来的特性…异步加载唯一的好处就是可以减少网页打开速度,坏处是可能数据收集不到…

    另外,没必要将GA代码分开,这种分开也不会带来任何好处,除非你页面的JS真的多到再多两三行就卡机了…懂技术的话可以适当看看GA的代码…

    • 你说的好处只是结果,而其实现原理就是我上面提供的解释。
      建议你仔细阅读一下文中提到的 Google 提供的说明。

      • 你的解释无非是同步阻止了网页加载,这个我了解。但是你文中的第二节与第三节都是描述有误的。

        “如果你把整个上面的全部代码都放置在一起不做任何改变,那么就跟原来的非异步加载方法一样”
        这话是错的…分开放是可以,但是全部放一起也是异步加载,无论你放页头、页尾,异步就是异步,不会影响你网页的加载速度…

        还有LZ理解有误的,是说异步“就是开始记录统计数据和对这些统计数据进行处理(比如上传到 Google 服务器)可以不同步的进行”。这不是异步,这仅仅是为了弥补异步而采纳的一种措施…因为异步会丢失数据…

        最后建议LZ可以再深入了解一些。

        • 谢谢!
          那里的说法的确不对,仅仅的是表达上的问题,毕竟是不一样的。我对这部分做些修改。
          但是其它的没错。之所以说 2 段放到一起会影响加载速度,是因为页面加载过程中需要分出时间来处理 Google 的统计代码(.js )文件。
          至于“异步”的科学解释是什么,请原谅我懒得去查了,或许你可以给个完整的说明。我只知道,这些代码——为了提高网页加载速度,也许提高不多——应该这么去使用。我想,我的解释非常通俗易懂。

        • 你好,已经将相关部分做了修改,请再看看。
          另外,如果有关于“异步加载”的权威解释,还请不吝提供一下。
          非常感谢!

  5. 异步加载对数据的统计有没有影响呢?为什么在1月对GA代码进行了异步加载之后,我的访问次数很多都显示not set?

    • 要说有影响,应该是更准确了吧。
      not set 是指某个统计指标缺失吧。不知道你指的是哪个指标?有些设备、操作系统、浏览器类型等可能做了屏蔽,统计的时候就收集不到某些信息,对应的信息就会显示为 not set。

  6. 作为一个小菜鸟,支持楼主的观点!

  7. 引用通告: Google Analytics(谷歌分析)工作原理及基本应用 | Drupal与高性能网站架构

  8. 引用通告: LazyLoad 与百度推广投放方式选择 | 水景一页

  9. 引用通告: Google Adsense 广告的四种投放方式 | 水景一页

  10. 不懂就麻烦不要误人子弟,懂JS不?红色部分只是变量赋值,执行起来在1MS之内,下面的代码才需要引用Google服务器资源,才需要Google服务器统计 计算,你就是把红色的装到用户口袋里去,也得待下面执行完才行,有必要分开放? 分开之后,1MS的性能都提升不了。我靠。

    • 能有高手来小站评论实在是小站莫大的荣幸!
      相信您是不屑于细看,所以没发现文中已经对您所提问题作了说明。分开放的目的在于将下载 ga.js 的代码放在页面最后,但是变量定义还是在页面头部。
      P.S. 对于希望分开放置这两段代码的用户,Google 技术文档中的建议也是如此。

时间过去太久,评论已关闭。
如果您有话要说,请到讨论区留言并给出此文章链接。
谢谢您的理解 :-)