日期:2014-05-16  浏览次数:20255 次

延迟异步加载 JavaScript

为了增强网站的交互效果,我们常常会使用 jQuery,ExtJS 或者自己编写的 JS 类库,这些文件通常储存在页面外部文件中,体积比较巨大,在页面加载的时候需要比较长的时间,并且会阻碍后面的资源加载。

最近在查看 Google Analytics 统计代码的时候,发现 Google 并没有直接用 <script src="..."></script> 的形式来加载 js 文件,而是采用了异步加载的方法:

(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 标签,赋予 async 属性使其能够异步加载,再指定需要加载的 js 文件的路径。当上面这段代码运行后,页面头部会多出这样的一行:

<script src="http://www.google-analytics.com/ga.js" async="" type="text/javascript"></script>

把 Google Analytics 的统计代码改一下,使其能够用在我平时做的项目中:

(function() {
    var s = document.createElement('script');
    s.type = 'text/javascript';
    s.async = true;
    s.src = 'http://CodeCTO.com/script.js';
    var x = document.getElementsByTagName('script')[0];
    x.parentNode.insertBefore(s, x);
})();

大家可以对比一下启用异步加载前后的瀑布图。

。。。。

可以看到,如果没有使用 async 属性的话,后面的资源必须等 js 文件加载完以后才开始加载。

使用 async 属性以后,页面上的两个资源可以同时加载。

注意: async 是一个 HTML5 属性,浏览器必须支持 HTML5 才有效果。

还有一种情况,某些 js 文件根本不需要这么快就加载到页面里,怎么办?可以参考我以前写的 JavaScript 事件监听绑定 ,让 js 文件在页面所有内容都完全载入以后才加载进来。

(function() {
    function async_load(){
        var s = document.createElement('script');
        s.type = 'text/javascript';
        s.async = true;
        s.src = 'http://CodeCTO.com/script.js';
        var x = document.getElementsByTagName('script')[0];
        x.parentNode.insertBefore(s, x);
    }
    if (window.attachEvent){
        window.attachEvent('onload', async_load);
    }else{
        window.addEventListener('load', async_load, false);
    }
})();

使用这个方法后,js 文件在左右资源加载完成后在开始载入。

当然这个方法还有一个弊端:如果页面上的外部资源(例如图片)非常多的话,这个 js 文件可能要等待很久才开始加载,怎么解决这个问题呢?熟悉 js 的同学相信已经想到了解决的办法,或者,你可以参考一下 jQuery 的 $(document).ready() 方法。