正确使用 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 来直接查找英文文章的习惯。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

雁过留声,人过留名

您的电子邮箱地址不会被公开。 必填项已用 * 标注

特别提示:与当前文章主题无关的讨论相关但需要较多讨论求助信息请发布到水景一页讨论区的相应版块,谢谢您的理解与合作!请参考本站互助指南
您可以在评论中使用如下的 HTML 标记来辅助表达: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>