有这么一张图我觉得挺清晰明了的:
解释:
1、其中Script execution采用的是v8 js引擎去执行,而HTML parsing采用的是GUI渲染线程,这两个线程是互斥的,不能同时进行;Script download是使用异步http请求线程(请求并下载js文件);
2、对于这句话“每一个defer属性的脚本都是在页面解析完毕之后,按照原本的顺序执行,同时会在document的DOMContentLoaded之前执行。”--------------HTML5规范要求脚本执行应该按照脚本出现的先后顺序执行且会在document的DOMContentLoaded之前执行,但在不遵循HTML5规范的较旧浏览器中,可能会有差异;
3、async的js在下载完后会立即执行(因此脚本在代码中的顺序并不是脚本所执行的先后顺序,有可能后面出现的脚本先执行)
同时存在defer script、async script、 内联 script的情况下,async加载完成即开始执行,顺序可能是在内联 script之前也有可能之后,这种情况下是混序的,会受到脚本的大小、当时的网络环境等影响;
4、大部分情况下,按照HTML5的规范,且现在的绝大多数现代浏览器(如 Chrome、Firefox、Safari、Edge 等)都是遵循HTML5规范的,对于defer 脚本:每一个defer属性的脚本都是在页面解析完毕之后,按照原本的顺序执行,同时会在document的DOMContentLoaded之前执行!
尝试
<script src="./test1.js" defer></script> // console.log('test1')
<script src="./test2.js" defer></script> // console.log('test2')
<script>
console.log('test3')
</script>
// 结果
test3 => test1 => test2