当您在 HTML 文档中使用 <script>
标签引入 JavaScript 时,defer
和 async
属性可以控制脚本的加载和执行方式,它们之间的区别主要在于脚本加载的时间以及执行的时机。
defer 属性
使用 defer
属性的 <script>
标签会让脚本在文档解析期间异步下载,但是会延迟到整个文档解析完毕之后、DOMContentLoaded 事件触发之前执行。这意味着带有 defer
的脚本总是在文档解析完成之后执行,保证了执行时 DOM 已经完全构建好。
例子:
html<script src="example.js" defer></script>
如果您有多个带有 defer
属性的脚本,它们将按照在文档中出现的顺序执行,即便有些脚本可能会比其他脚本更早下载完成。
async 属性
而 async
属性也允许脚本在文档解析时异步下载,但是它一旦下载完成就会立即执行,这可能会在文档的其余部分尚未解析完毕时发生。因此,使用 async
的脚本不能保证按照在页面中出现的顺序执行,也无法保证 DOM 完全构建完成。
例子:
html<script src="example.js" async></script>
async
适用于那些不依赖于其他脚本且不依赖于 DOM 的脚本,例如,广告加载或者埋点脚本。
总结
defer
确保脚本在文档完全解析和 DOM 构建完成后,但在 DOMContentLoaded 事件之前执行。async
确保脚本在下载完成后尽快执行,但可能会打断文档的解析过程。- 没有这两个属性的
<script>
标签会立即下载并阻塞文档解析直到脚本执行完成。
在实际应用中,选择 defer
或 async
取决于脚本对文档解析的依赖性,以及脚本之间的依赖关系。如果您需要确保脚本按照顺序执行,并且在 DOM 完全构建后执行,那么 defer
是更好的选择。如果脚本的执行顺序不重要,并且想尽快获取并执行脚本,可以使用 async
。