实现异步加载js的几种方式:defer、async、动态创建script标签

Daming 2019-05-10
0条评论 1,068 次浏览
Daming 2019-05-100条评论 1,068 次浏览

没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。

defer

<script type="text/javascript" defer="defer">
//do something
</script>

defer 属性规定是否对脚本执行进行延迟,直到页面加载为止。

有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但脚本 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。

只有 Internet Explorer 支持 defer 属性。

脚本将在页面完成解析时执行。

async

<script type="text/javascript" src="demo_async.js" async="async"></script>

有 async,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。
async 属性仅适用于外部脚本(只有在使用 src 属性时)
脚本可用后会立即执行

defer 与 async 比较:

defer 与 async 在下载js这块是一样,在解析html的同时异步请求外部js,区别是脚本何时执行。

当我们的脚本不会修改 DOM 或 CSS 时,推荐使用 async 。

更兼容的通用做法

动态创建 script 标签,实现异步加载js:

     function loadScript(src, callback) {
        if (!src) return src;
        var script = document.createElement("script");
        script.onload = function () {
            if (!!callback) callback();
        };

        script.src = src;
        document.head.appendChild(script);

    }

   loadScript("https://cdn.bootcss.com/lodash.js/4.17.15/lodash.core.min.js", function () {
     console.log("lodash 加载完成")
    });

百度统计的 统计代码就是这样实现异步加载的:

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

1+

发表评论

电子邮件地址不会被公开。