1. defer,只支持IE
  2. async:
  3. 创建script,插入到DOM中,加载完毕后callBack

答:
1,什么是异步加载js

  • 使js文件脱离html解析的瀑布流加载,从而使js可以并行下载。

2,为什么要异步加载

一般写法将js放在head中,而且默认方式是同步加载,这就会导致在进行js加载的过程中,无法在其加载完成前对后续的内容进行操作,造成页面内阻塞,对用户体验很不友好。

3.如何异步加载

之前我们的写法就是把外部js或js放在body后或内部js放在body结束标签之前,这样会使至少先把一些基本内容加载出来而不会让人等太久,值得注意的是js中一般包含对dom的操作,如果放在body前,就可能出现空白或闪烁,而且js如果放在body内即结束标签之前,则无法获得onload和readystate,需要好好分析。

1. 而比较常用的写法是动态的添加一个script标签,叫做Script DOM Element:

//立即执行函数
    (function(){
        //创建一个script标签
    var scriptTag = document.creatElement("script");
        //h4前type必须加上,h5可以不加
    scriptTag.type = "text/javascript";
        //h5新增的,用这种方法可以不写
    scriptTag.async = true;
        //你的地址
    scriptTag.src = "js地址";
        //获取head标签
    var headTag = document.getElementsByTagName("head")[0];
        //在已有子节点前插入该标签,其实也可以用appendChild
    headTag.insertBefore(scriptTag, headTag.firstChild);
    })()

但是这个函数又放在哪里呢,我一时间没查到,不过想想应该是放在head中的,毕竟它也是同步加载的。但是这种方法有个问题,它会阻止onload函数的触发,但是我们有很多时候都需要使用这个函数来渲染一些其他东西,所以可以将该函数也放在onload中:

(function(){
        //兼容ie,因为ie的window上没有addEventListener
    	if(window.attachEvent){
        	window.attachEvent("load", asyncLoad);
        //非ie
        }else{
        	window.addEventListener("load", asyncLoad);
        }
        var asyncLoad = function(){
        	var scriptTag= document.createElement('script'); 
            scriptTag.type = 'text/javascript'; 
            scriptTag.async = true; 
            scriptTag.src ="你的地址"; 
            var headTag= document.getElementsByTagName('head')[0]; 
            headTag.insertBefore(scriptTag, headTag);
        }
    )();

2. defer

该属性是h5新属性,只有ie可以用,主要可以延迟脚本的执行;

有3点需要注意:
1. defer只适用于外联脚本,如果script标签没有指定src属性,只是内联脚本,不要使用defer
2. 如果有多个声明了defer的脚本,则会按顺序下载和执行
3. defer脚本会在DOMContentLoaded和load事件之前执行

3. script 标签上添加 async 属性

该属性声明外部js的异步加载;

也是3点:
1. 只适用于外联脚本,这一点和defer一致
2. 如果有多个声明了async的脚本,其下载和执行也是异步的,不能确保彼此的先后顺序
3. async会在load事件之前执行,但并不能确保与DOMContentLoaded的执行先后顺序

4. 创建并插入 iframe,让它异步执行 js