异步加载
先了解下同步加载:
我们平时最常使用的就是这种同步加载形式:
<script src="http://demo/script.js"></script>
同步模式,又称阻塞模式,会阻止浏览器的后续处理,停止了后续的解析,因此停止了后续的文件加载(如图像)、渲染、代码执行。
js 之所以要同步执行,是因为 js 中可能有输出 document 内容、修改dom、重定向等行为,所以默认同步执行才是安全的。
以前的一般建议是把<script>放在页面末尾</body>之前,这样尽可能减少这种阻塞行为,而先让页面展示出来。
异步加载的三种方案
1. defer
异步加载,等到dom文档全部解析完才会被执行。
兼容IE9以下,低版本的其他浏览器不兼容,建议使用。
使用方法:外部js
<script type="text/javascript" src="demo.js" defer="defer"></script>
内部js:
<script type="text/javascript" defer="defer">var i = 0;</script>
具体自己测试,部分方法没用!!!
2. aysnc 异步加载,加载完就执行,aysnc 只能加载外部脚本,不能把 Js 写在 内部。
不兼容 IE 9以下
<script type="text/javascript" src="demo.js" aysnc = "aysnc"></script>
3. DOM中插入。
<script type="text/javascript" > var script = document.createElement('script'); script.type = 'text/javascript'; script.src = 'ku.js';//执行这句后就开始下载这个js文件 document.head.appendChild(script) </script>
如果想要使用那个script里面的参数,需要等它下载完才可以,
使用
script.onload = function () { //这里写的事件会在它下载完后执行, //不执行低版本IE }
时间线
1. 先创建一个Document对象,开始解析web页面。这个阶段的document.readyState = "loading" 。
2. 遇到 link 外部 css,创建线程加载,并继续解析文档。
3. 遇到 script 外部 js ,并且没有设置 async , defer,浏览器加载,并阻塞,等待js 加载完成并执行该脚本,然后继续解析文档。
4. 遇到外部 js,并且有设置async,defer,浏览器创建线程加载,并继续解析文档。
对于async属性的脚本,脚本加载完成后立即执行。(异步加载禁止使用document.write)
5. 遇到 img 等,先正常解析dom 结构,然后浏览器异步加载 src ,并继续解析文档。
6. 当文档解析完成, document.readyState = 'interactive'。
7. 文档解析完成后,所有设置的defer的脚本会按照顺序执行。()
8. 文档解析完成后,document对象触发DOMContentLoaded事件(没卵用)
9.当所有的脚本加载完成并执行后,img等加载完成后,document.readyState = "complete",window对象触发load 事件。
10.从此,以异步响应方式处理用户输入,网络事件等。页面按照你理解的顺序执行。
理解不了?背也要背下来!