简述JavaScript标签中 defer和 async属性的区别 ?
参考回答
在 HTML 中,<script> 标签的 defer 和 async 属性用于控制外部 JavaScript 文件的加载和执行顺序。它们的作用是让 JavaScript 脚本的加载不阻塞页面的渲染,提高网页加载性能。尽管两者的目的是相似的,但它们的行为有所不同:
defer:脚本文件会被延迟执行,直到 HTML 文档完全解析完成。并且,所有带defer的脚本会按顺序依次执行。async:脚本文件会异步加载并执行,一旦脚本加载完成就立即执行,执行顺序不保证。
详细讲解与拓展
1. defer 属性
当在 <script> 标签中使用 defer 属性时,浏览器会异步加载该脚本文件,但会保证脚本执行顺序与它们在 HTML 中的顺序一致。脚本的执行会等到整个 HTML 文档解析完成后再进行,但不会阻止页面渲染。
- 特点:
- 脚本异步加载,解析 HTML 时不会阻塞页面的渲染。
- 执行顺序和
<script>标签的出现顺序一致。 - 只有在 HTML 文档完全解析后,脚本才会执行。
<!DOCTYPE html>
<html>
<head>
<title>defer 示例</title>
</head>
<body>
<h1>页面标题</h1>
<script src="script1.js" defer></script>
<script src="script2.js" defer></script>
</body>
</html>
在上面的例子中,script1.js 和 script2.js 会按顺序加载,但只会在 HTML 文档解析完成后执行。
2. async 属性
当在 <script> 标签中使用 async 属性时,浏览器会异步加载该脚本文件,一旦脚本加载完成就立即执行。执行顺序不依赖于脚本在 HTML 中的位置,而是取决于哪个脚本最先加载完成。
- 特点:
- 脚本异步加载,不会阻塞页面渲染。
- 执行顺序不保证,取决于脚本加载的先后。
- 一旦加载完成,立即执行,可能会在文档解析过程中执行。
<!DOCTYPE html>
<html>
<head>
<title>async 示例</title>
</head>
<body>
<h1>页面标题</h1>
<script src="script1.js" async></script>
<script src="script2.js" async></script>
</body>
</html>
在这个例子中,script1.js 和 script2.js 会并行加载,哪个先加载完成,哪个先执行。因此,它们的执行顺序是不确定的。
3. defer 与 async 的主要区别
| 特性 | defer |
async |
|---|---|---|
| 加载方式 | 异步加载 | 异步加载 |
| 执行顺序 | 按照 <script> 标签的顺序执行 |
执行顺序不确定,取决于哪个脚本先加载完成 |
| 执行时机 | 等待 HTML 完全解析后执行 | 一旦脚本加载完成就立即执行 |
| 与页面渲染的关系 | 不阻塞渲染,文档解析和脚本执行并行 | 不阻塞渲染,文档解析和脚本执行并行 |
| 适用场景 | 适合需要按顺序执行的脚本 | 适合独立且无顺序依赖的脚本 |
4. 使用场景
defer:适用于需要按顺序执行的脚本,尤其是当脚本需要访问 DOM 时,使用defer可以确保 DOM 元素已经加载完毕。例如,多个插件的初始化脚本通常使用defer。-
async:适用于独立的、没有顺序依赖的脚本,例如第三方分析工具、广告服务等,它们可以在任何时候加载并立即执行,不依赖于页面的其他内容。
总结
defer 和 async 属性都能让 JavaScript 脚本异步加载,从而提高页面的加载速度。defer 保证脚本按顺序执行,并且等 HTML 完全解析后执行;async 则在脚本加载完成后立即执行,执行顺序不固定。选择使用哪个属性取决于脚本之间的依赖关系和需要的执行顺序。