javascript 之 js 代码在浏览器中的各种加载方式

同步加载与异步加载的形式

同步加载

我们平时最常使用的就是这种同步加载形式:

<script src="myJs.js"></script>
  

同步模式,又称阻塞模式,会阻止浏览器的后续处理,停止了后续的解析,因此停止了后续的文件加载(如图像)、渲染、代码执行。
js 之所以要同步执行,是因为 js 中可能有输出 document 内容、修改 dom、重定向等行为,所以默认同步执行才是安全的。
以前的一般建议是把 <script> 放在页面末尾 </body> 之前,这样尽可能减少这种阻塞行为,而先让页面展示出来。

常见异步加载(Script DOM Element)

<script>
    (function() {
        var s = document.createElement('script');
        s.type = 'text/javascript';
        s.async = true;
        s.src = 'myJs.js';
        var x = document.getElementsByTagName('script')[0];
        x.parentNode.insertBefore(s, x);

    })();
<script>
  

异步加载又叫非阻塞,浏览器在下载执行 js 同时,还会继续进行后续页面的处理。
这种方法是在页面中 <script> 标签内,用 js 创建一个 script 元素并插入到 document 中。这样就做到了非阻塞的下载 js 代码。

将 js 代码包裹在匿名函数中并立即执行的方式是为了保护变量名泄露到外部可见,这是很常见的方式,尤其是在 js 库中被普遍使用。

<script>
(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>
  

但是,这种加载方式在加载执行完之前会阻止 onload 事件的触发,而现在很多页面的代码都在 onload 时还要执行额外的渲染工作等,所以还是会阻塞部分页面的初始化处理。

onload 时的异步加载

<script>
(function() {
    function async_load(){
        var s = document.createElement('script');
        s.type = 'text/javascript';
        s.async = true;
        s.src = '';
        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);

})();
</script>