script标签中的async和defer属性(附图)

在HTML中会遇到一下三类script

<script src=""></script>
<script src="" async></script>
<script src="" defer></script>

那么这三类有什么区别呢?

script

浏览器在解析HTML代码的时候,如果遇到一个没有任何属性的script标签,就会暂停解析HTML,先发送网络请求获取该js脚本的代码并解析,然后让js引擎执行该代码,当js代码执行完毕后恢复解析。整个过程如下图所示:


script.png

可以看到,script阻塞了浏览器对HTML的解析,如果获取js脚本的网络请求迟迟得不到响应后者js脚本执行时间过长,都会导致白屏用户看不到内容。

async script

async表示异步,但浏览器遇到带有async属性的script时,请求该脚本的网络请求是异步的,不会阻塞浏览器解析HTML,一旦网络请求回来之后,分一下两种情况:
-此时HTML还没有解析完,浏览器会暂停解析HTML,先让js引擎执行代码,执行完毕后再解析HTML;
-此时HTML代码解析完成,直接执行js代码;


第一种情况.png

第二种情况.png

所以async是不可控的,执行时间不确定,如果在异步js脚本中获取某个DOM元素,有可能获取到也有可能获取不到而且如果存在多个async的时候,他们之间的执行顺序也是不确定的,完全依赖网络传输结果,谁先到执行谁。

defer script

defer表示延迟,当浏览器遇到带有defer属性的script的时候,获取该脚本的网络请求也是异步的,不会阻塞浏览器解析HTML,一旦网络请求回来之后,如果此时HTML代码还没有解析完,浏览器不会暂停解析HTML代码并执行js代码,而是等待HTML解析完毕以后再执行js代码,如图:


defer.png

如果存在多个defer script标签,浏览器会保证他们按照在HTML中出现的顺序执行,不会破坏js脚本之间的依赖关系。
总结:
script 标签 JS 执行顺序 是否阻塞解析 HTML
<script> 在 HTML 中的顺序 阻塞
<script async> 网络请求返回顺序 可能阻塞,也可能不阻塞
<script defer> 在 HTML 中的顺序 不阻塞

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容