script标签中的defer和async属性的区别

如果script标签中没有defer或async属性,浏览器在渲染中遇到script标签就会停止渲染,下载执行js代码,等待JS执行完毕后,浏览器再从中断的地方恢复渲染。这就会造成浏览器阻塞,如果你想首屏渲染的越快,就越不应该在首屏就加载 JS 文件,这也是都建议将 script 标签放在 body 标签底部的原因。当然在当下,并不是说 script 标签必须放在底部,因为你可以给 script 标签添加 defer 或者 async 属性,异步加载script。

defer (延迟执行)
<script defer src="script.js"></script>

defer 属性表示延迟执行引入的 JavaScript,即这段 JavaScript 加载时 HTML 并未停止解析,这两个过程是并行的。整个 document 解析完毕且 defer-script 也加载完成之后(这两件事情的顺序无关),会执行所有由 defer-script 加载的 JavaScript 代码,如果有多个defer的script标签,会按顺序执行,然后触发 DOMContentLoaded 事件。
应用场景:

async (异步加载)
<script async src="script.js"></script>

async属性表示异步执行引入的 JavaScript,即javaScript下载时html并未停止解析,等到javaScript下载完成,html就停止解析,执行javaScript代码,等待javaScript执行完毕,浏览器再继续渲染。需要注意的是,这种方式加载的 JavaScript 依然会阻塞 load 事件。换句话说,async-script 可能在 DOMContentLoaded 触发之前或之后执行,但一定在 load 触发之前执行。如果有多个js脚本,哪个先下载完成就先执行哪个,跟书写顺序没有关系。

defer 和 async 的区别

我们可以先看一下 单纯的script和带defer和async的区别,如下图:
其中蓝色代表js脚本网络下载时间,红色代表js脚本执行,绿色代表html解析
其中蓝色代表js脚本网络下载时间,红色代表js脚本执行,绿色代表html解析.
(1) defer 是不会阻塞html解析的,它是等DOM加载完之后再去执行JavaScript代码;async是JavaScript下载完成,就会立即执行代码,等待执行完之后才继续解析HTML。
(2) 在加载多个JS脚本的时候,async是无顺序的加载,而defer是有顺序的加载。

应用场景

defer:如果你的脚本代码依赖于页面中的DOM元素(文档是否解析完毕),或者被其他脚本文件依赖。
async:如果你的脚本并不关心页面中的DOM元素(文档是否解析完毕),并且也不会产生其他脚本需要的数据。

总结:如果不能确定,使用defer要比async稳定一些。

发布了23 篇原创文章 · 获赞 7 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/diwang_718/article/details/105532049