script标签中defer和async

在现代Web开发中,优化页面加载速度是提升用户体验的关键之一。JavaScript 文件的加载和执行方式对页面性能有着重要影响。HTML 中的 <script> 标签有两个属性 deferasync,它们可以帮助我们更好地控制脚本的加载和执行行为。


1. 默认行为

在讨论 deferasync 之前,我们先回顾一下 <script> 标签的默认行为。当浏览器解析到 <script> 标签时,它会立即停止 HTML 文档的解析,下载并执行脚本文件,然后再继续解析 HTML。这种行为被称为“阻塞”行为,因为它会延迟页面的渲染。

1
<script src="script.js"></script>

2. async 属性

async 属性告诉浏览器异步加载脚本文件。这意味着浏览器在下载脚本的同时,不会阻塞 HTML 文档的解析。脚本一旦下载完成,浏览器会立即执行它,此时 HTML 解析可能会被暂停。

1
<script async src="script.js"></script>

特点:

  • 异步加载:脚本的下载不会阻塞 HTML 解析。
  • 立即执行:脚本下载完成后立即执行,可能会中断 HTML 解析。
  • 执行顺序不确定:如果有多个 async 脚本,它们的执行顺序可能与它们在文档中出现的顺序不一致。

使用场景:

  • 适用于那些不依赖于其他脚本或 DOM 内容的独立脚本,例如广告脚本、统计脚本等。

3. defer 属性

defer 属性也告诉浏览器异步加载脚本文件,但与 async 不同的是,defer 脚本会在 HTML 文档解析完成后,按照它们在文档中出现的顺序依次执行。

1
<script defer src="script.js"></script>

特点:

  • 异步加载:脚本的下载不会阻塞 HTML 解析。
  • 延迟执行:脚本会在 HTML 解析完成后,DOMContentLoaded 事件触发之前执行。
  • 执行顺序确定:多个 defer 脚本会按照它们在文档中出现的顺序依次执行。

使用场景:

  • 适用于那些需要在 DOM 解析完成后执行的脚本,尤其是那些依赖于 DOM 或其他脚本的脚本。

4. deferasync 的区别

特性 async defer
加载行为 异步加载,不阻塞 HTML 解析 异步加载,不阻塞 HTML 解析
执行时机 下载完成后立即执行 HTML 解析完成后执行
执行顺序 不确定 按照文档中的顺序执行
适用场景 独立脚本,不依赖其他脚本或 DOM 依赖 DOM 或其他脚本的脚本

5. 总结

  • 如果你有一个独立的脚本,不需要等待 DOM 或其他脚本,可以使用 async
  • 如果你的脚本依赖于 DOM 或其他脚本,应该使用 defer