defer
和async
是HTML <script>
标签的两个属性,用于控制JavaScript文件的加载和执行方式。这两个属性可以帮助优化页面加载性能,但它们在处理脚本的顺序和时机上有重要区别。
defer
属性
- 加载方式:脚本文件会异步加载,与HTML文档的解析并行进行。
- 执行顺序:脚本会按照它们在文档中出现的顺序执行。
- 执行时机:所有
defer
脚本会在HTML文档完全解析(即DOM构建完成)之后,但在DOMContentLoaded
事件之前执行。
使用示例:
<!DOCTYPE html>
<html>
<head>
<script src="script1.js" defer></script>
<script src="script2.js" defer></script>
</head>
<body>
<h1>Hello, world!</h1>
</body>
</html>
在这个例子中,script1.js
和 script2.js
会并行加载,并在HTML文档解析完毕后按照它们在文档中出现的顺序依次执行。
async
属性
- 加载方式:脚本文件会异步加载,与HTML文档的解析并行进行。
- 执行顺序:脚本会在下载完成后立即执行,执行顺序取决于文件的加载完成顺序,而不是它们在文档中的出现顺序。
- 执行时机:每个
async
脚本在加载完成后立即执行,可能在HTML文档解析过程中,也可能在解析完成之后。
使用示例:
<!DOCTYPE html>
<html>
<head>
<script src="script1.js" async></script>
<script src="script2.js" async></script>
</head>
<body>
<h1>Hello, world!</h1>
</body>
</html>
在这个例子中,script1.js
和 script2.js
会并行加载,哪个脚本先加载完成就先执行。因此,它们的执行顺序可能与它们在文档中的出现顺序不同。
关键区别总结
-
执行顺序:
defer
:按文档中出现的顺序执行。async
:按加载完成的顺序执行,可能与文档中出现的顺序不同。
-
执行时机:
defer
:在HTML文档完全解析后(但在DOMContentLoaded
事件之前)执行。async
:加载完成后立即执行,可能在HTML解析过程中或解析完成之后。
-
适用场景:
defer
:适用于依赖DOM元素的脚本,或需要按顺序执行的多个脚本。async
:适用于独立的、不依赖其他脚本的功能,如分析或广告脚本。
通过理解和正确使用这两个属性,可以更好地优化网页的加载性能和用户体验。