JS同步脚本&异步脚本async&延迟脚本defer
同步脚本
同步脚本,顾名思义是按脚本的书写顺序串行执行,所以也称为阻塞脚本。同步脚本会阻止浏览器的后续处理,停止后续的解析,只有在当前脚本下载并执行完成后才能进行下一步操作,因此一般建议把script标签放在body结尾处,这样尽可能减少页面阻塞。
<script src="a.js"></script>
<script src="b.js"></script>当页面中有多个脚本文件时的执行顺序:下载a.js,执行a.js,下载b.js,执行b.js。
异步脚本
异步脚本,会告诉浏览器立即开始下载并执行脚本,不必等到脚本下载和执行完成后再加载页面或页面中的其它脚本,因此一般不建议在异步脚本加载期间修改DOM。
<script src="a.js" async></script>
<script src="b.js" async></script>当页面中有多个脚本文件时的执行顺序:下载a.js,下载b.js,执行a.js和b.js的顺序取决于谁先下载完成。异步脚本保证会在load事件前执行,但可能会在DOMContentLoaded之前或之后。
延迟脚本
延迟脚本,会告诉浏览器立即下载脚本,但脚本的执行推迟到整个页面解析完毕后在执行。
<script src="a.js" defer></script>
<script src="b.js" defer></script>当页面中有多个脚本文件时的执行顺序:下载a.js,下载b.js,执行a.js,执行b.js。这个是理想的执行顺序,HTML5规范要求脚本应该按照它们出现的顺序执行,而且a.js和b.js都会在DOMContentLoaded事件之前执行,但是在实际的实现当中,延迟脚本不一定总会按顺序执行或者在DOMContentLoaded事件之前执行。
区别
首先我们需要了解,浏览器在渲染页面解析html是单线程的,是按顺序从上到下执行的解析,在遇到script标签时会停止html解析,执行script的下载和执行。
<script />:当解析到script标签的时候,因为script是同步执行的,所以html解析到script标签会停止,首先执行js脚本的下载,下载完成之后执行js脚本,然后在继续执行html的解析。<script async />:script标签中包含async时候,代表script是异步执行的,当html解析到script标签时不会停止,而是开启异步下载js脚本,当下载完成js脚本后,因为html解析是GUI渲染线程解析的,js是js引擎线程执行的,这两个线程互斥,js脚本执行完后才会继续执行html解析。<script defer />:script标签中包含defer时候,代表script是异步执行的,当html解析到script标签时不会停止,而是开启异步下载js脚本,等到html解析完毕之后才会执行js脚本。
