js同步加载
jst同步加载的缺点,加载工具方法会阻塞文档,使得js加载会影响页面效率,一旦网速不好,那么整个网站将会等待js加载而不进行后续渲染等工作
有些工具需要用到在加载,不用不加载
<script src="http://yourdomain.com/script.js"></script>
js异步加载
defer 加载,但是要等到dom文档全部解析完才会被执行,只有IE能用,也可以将代码写到内部
async 异步加载,加载完就执行,且只能加载外部脚本,不能把js 写到sript标签里
创建script,插入DOM中,加载完毕后callBack,
// var tools={
// test:function(){
// console.log("a")
// }
// }第三种
function test(){
console.log("a")
}//第一种和第二种,对应
function loadScript(url, callback) {
var script = document.createElement('script');//创建
script.type = "text/javascript";//设置
if (script.readyState) {
script.onreadystatechange = function () {
if (script.readyState == "complete" || script.readyState == "loaded") {
callback();//第一种
eval(callback);//一般不让用这个,与下面对应
tools[callback]()//这个比较好
}
}
} else {
script.onload = function () {
// Safari chrome firefox opera
callback();//第一种
eval(callback); //第二种
tools[callback]()//第三种
//下载完才会执行
}
}
script.src = url//异步下载,先执行绑定事件,在加载
document.head.appendChild(script)
}
loadScript("demo.js", function () {
test()
})//第一种,如果不写成函数的形式,test会被认为没有定义,无法识别
loadScript("demo.js", "test")//第二种和第三种 把callback变成字符串形式的就用到这个
一般常用第三种,因为第三种是按需加载,监控什么时候加载完,callback可以修改,按照自己的需要,改成数组的形式也可以
js加载时间线
1.创建Document对象,开始解析web页面,这个时候意味着js开始运行了,
这个阶段Document.readyState = "loading"。这个阶段的状态码是正在加载
2.遇到link外部css,创建线程加载,并继续解析文档。
3.遇到script外部js,并且没有设置async , defer ,浏览器加载,并阻塞,等待js加载完成并执行该脚本
,然后继续解析文档
4.遇到script外部js,并且设置有async,defer 浏览器创建线程加载,并继续解析文档,
对于async属性的脚本,脚本加载完成后立即执行 defer等到解析完执行(异步禁止使用docuemnt.write())。
docuemnt.write()这个方法特殊在,当你解析完全部文档之后,再调用了这个方法,他会把你之前解析的文档
全部清空,然后用它里面的文档流代替,其实也很好理解,这两个单词的意思就是,文档写作啥啥啥,,那就是把
啥啥啥取代了之前的文档
5.遇到img标签等,先正常解析dom结构,然后浏览器异步加载src,并继续解析文档
6.当文档解析完成,document.readyState = "interactive";动态活跃
7.文档解析完成后,所有设置有defer的脚本会按照顺序执行。defer是推迟的意思
8..当文档解析完成之后,document对象触发DOMContentLoaded事件,这也标志着程序执行从同步脚本
执行阶段,转化为事件驱动阶段,浏览器在这个时候可以开始发挥他的作用,可以监听事件了
9.当所有saync的脚本加载完成并执行后,img等加载完成后,document.readyState = "complete" 动态完成
window对象触发load事件
10.从此,页面以异步响应方式处理用户输入,网络事件等。
console.log(document.readyState);
document.onreadystatechange = function(){
console.log(document.readyState);
}
//这个可以验证一下这三个状态码
//事件和属性名的区别,时间名全是小写
DOMContentLoaded这个事件表示的是当Dom解析完毕之后执行,没有浪费浏览器运行效率,但是这个事件只能用addEventListener绑定
document.addEventListener('DOMContentLoaded',function(){
console.log("a");
},false)
jqury里面$(document).ready.function(){
}就是根据那三个状态码,封装的
window.onload 这个事件是在dom文档完全渲染完毕之后才会触发,那么如果网速不好的时候,有那么一丁点的数据没有加载完成,这个事件就不会执行,这是一个非常脱浏览器后腿的事件。