html文档是自上而下加载的
试想一下,在你的网页还没展现出来时,就匆匆忙忙运行了一大堆JavaScript,或者你想先执行完脚本1,再执行脚本2,结果却不如你所愿,这将会给用户带来多么糟糕的体验!!!
script和DOM是同步加载的
这里先假设某html的所有JavaScript没添加window.onload 或 $(function(){})等,由于script和DOM是同步解析的,也就是说后面的dom必须等它前面的所有script全部加载完,再配合前面的css的解析结果构建DOM树,后面script也必须等它前面的所有dom构建完,再解析该script
按照上面的流程,假如想head里的script操作某button元素,但是此时的dom却还没渲染完,那么可以在script里使用onload或者JQuery操作,作用是告诉浏览器,我先不执行,我要等到页面渲染完成再执行,当然,这不能否认html的自上而下执行,只不过执行到该script,浏览器先把它放到一边等页面加载完执行而已
图片或视频的加载是异步的
也就是说在加载css和dom的过程中假如出现图片链接,浏览器会额外去下载这个图片,并且不会阻塞到后面的资源解析,但图片的加载却受css样式的影响,比如用css给图片定义了宽高,那么图片的渲染之前,css必须加载完成
script的执行顺序
<script>
alert("test1");
alert!("test2");
alert("test3");
</script>
<script>
alert("test4");
</script>
上面的代码在浏览器浏览器只会弹出 “test4”,第一个script遇到错误的语法,于是直接报错并忽略该script块的执行,而跳转到下一个script块执行,也就是说每个script互不影响,但是他们各自的变量等资源却是共享的
<script>
setTimeout(function(){
alert("test1");
},100);
</script>
<script>
alert("test2");
</script>
上面的代码会先弹出 test2,再弹出 test1,第一个script要等到100ms才会执行,于是浏览器会等100ms后才把该script装入到执行队列,而先把第二个script装入执行队列,也就是说,script之间,假如前面的script处于阻塞状态,那么就会先执行后面script,直到前面的阻塞结束
window.onload = function(){
setTimeout(function(){alert("test1")},100);
alert("test2");
setTimeout(function(){alert("test3")},100);
alert("test4");
}
上面的代码弹出顺序依次 test2->test4->test1->test3, 同样的理由,虽然test1在前面,但是被阻塞了100ms,所以浏览器会把被阻塞的代码放到另一个队列,先执行后面直接可以执行的代码
外部样式和外部脚本
外部样式和外部脚本的加载也是异步的,也就是说在加载外部文件的时候,不会阻塞到后面dom等的解析,外部脚本执行没有async、defer的属性时,会被外部样式阻塞,也就是说要等到外部css加载完才会执行外部脚本,添加async或defer就不会受到阻塞