默认情况下的javascript是同步加载的,这里的加载可以理解成为解析执行。也就是js加载时是阻塞的,先加载完js,在加载css和dom。过多js加载会影响页面效率,一旦网速不好,那么整个网站将会等待js加载而不进行后续渲染工作。所以这时就会设置异步加载
常见的异步加载有三种方法:
1.在script标签中设置defer,等待dom解析完成才会执行,但是这个方法有局限性,只有IE才能用
<script defer></scrpit>
2.async,等待dom加载完成才会执行
<script async></script>
3.动态添加script标签
function loadScript(url,callback){
var script = document.createElement("script");
script.type = "text/javascript";
if(script.readyState){//兼容IE
script.onreadystatechange = function(){
if(script.readyState =="complete" || script.readyState == "loaded"){
obj[callback]()
}
}
}else{
script.onload = function(){
obj[callback]()
}
}
script.src = "06.js";
document.head.appendChild(script);
}
loadScript("06.js","test")
时间线:
1.创建Document对象,开始解析Web页面,此阶段document.readyState = 'loading'
2.遇到link外部js,创建线程加载,并继续解析文档
3.遇到script外部js,并且没有设置async、defer,浏览器加载并阻塞,等待js加载完成并执行该脚本,继续解析文档
4.遇到script外部js,并且设置有async、defer,浏览器创建线程,并继续解析文档,不能使用document.write()
5.遇到img等,先正常解析dom结构,然后浏览器异步加载src,并继续加载解析文档
6.当文档解析完成,document.readyState = 'interactive';
7.文档解析完成后,所有设置有defer的脚本会按照顺序执行。
8.document对象触发DOMContentLoaded事件,这也标志着程序执行从同步脚本执行阶段,转化为事件驱动阶段
9.当所有async的脚本加载完成并执行后,img等加载完成后,document,readyState = 'complete',windown对象触发load事件
10.从此,以异步响应方式处理用户输入、网络事件等