从统计代码来谈JS加载的优化

我有这么一个职业病,每次发现页面很卡,不管谁的网站,都会F12调出Chrome控制台来调试,看看是什么原因导致。
原因其实不外乎这几种:
1、页面文档的加载
2、css/js 的加载

这边就 js 说说前端的加载优化,以统计代码加载为例。

非异步加载

<!-- 最原始的,腾讯分析、cnzz精简版就是这种 -->
<script type="text/javascript" src="http://tajs.qq.com/stats?sId=xxx" charset="UTF-8"></script>


<script type="text/javascript">

// 用js 在当前位置插件统计代码。cnzz、百度统计旧版就是用这个
var _bdhmProtocol = (("https:" == document.location.protocol) ? " https://" : " http://");
document.write(unescape("%3Cscript src='" + _bdhmProtocol + "hm.baidu.com/h.js%3Fxxx' type='text/javascript'%3E%3C/script%3E"));
</script>

非异步加载,会影响 DOMContentLoaded, 比如 $(document).ready() 延迟,它绑定一些事件,页面效果,都等这些统计代码加载完才生效。
而且这种情况下,如果这些被加载的代码又以同样的方法加载其他js,则 DOMContentLoaded 会更延后。
所以最好不要用这种方法。

异步加载

// 百度统计,创建 script 元素,插入第一个 script 元素前面
(function() {
  var hm = document.createElement("script");
  hm.src = "//hm.baidu.com/hm.js?xxx";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();

///////////////////////////////
// 谷歌分析(ga),其中部分代码跟百度统计一样
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-xxx-1', 'auto');
  ga('send', 'pageview');

百度统计跟ga是异步加载,则不会影响 DOMContentLoaded 。但在Chrome、Firefox、Opera、IE11+ 会影响onload,像Chrome的favicon就一直在转圈圈。
这样还不易接受的话,可以用 setTimeout 来解决,让浏览器当成是要延迟加载的。

var _hmt = _hmt || [];
    setTimeout(function(){
        (function() {
            var hm = document.createElement("script");
            hm.src = "//hm.baidu.com/hm.js?xxx";
            var s = document.getElementsByTagName("script")[0];
            s.parentNode.insertBefore(hm, s);
        })();
    },0);

不过这里要注意。这样的统计代码最好写在最前,防止之前的代码出错导致统计代码不被执行。
也可以把这些统计代码写到 一个 stat.js 再引入进来防止被其他错误代码影响,虽比较绕。
于是,我赶紧把一些统计代码用上面的形式加载。把 hm.src 变量替换掉就OK了。

这里说的是统计代码,实际上可以推广到与业务不相关的一些js都可以这样加载。

 

发表评论