Skip to content

普通的 <script>、defer 和 async 的区别

在 HTML 中插入脚本时,通常使用script标签引用,script标签有三种不同的加载方式:普通、defer和async。

1. 普通的 <script> 标签

  • 加载方式: HTML 解析会暂停,直到脚本加载完成并立即执行。
  • 执行顺序: 按照脚本在页面中出现的顺序执行(同步执行)。
  • 适用场景: 依赖于 DOM 的脚本,或者需要确保脚本按顺序执行。

流程:

  1. 遇到 <script> 标签时停止 HTML 解析。
  2. 加载脚本。
  3. 加载完成后立即执行脚本。
  4. 继续解析 HTML。

2. <script defer>

  • 加载方式: 脚本与 HTML 并行加载。
  • 执行方式: HTML 完全解析完成后,按顺序依次执行。
  • 执行顺序: 严格按照 <script> 在文档中的顺序执行。
  • 适用场景: 不依赖 DOM,适合页面初始化时运行的脚本,例如页面依赖的模块或框架。

流程:

  1. HTML 解析时,脚本在后台并行加载。
  2. HTML 解析完成后,按顺序执行已加载的脚本。

3. <script async>

  • 加载方式: 脚本与 HTML 并行加载。
  • 执行方式: 脚本加载完成后立即执行,不等待 HTML 解析完成。
  • 执行顺序: 无法保证,可能会乱序执行多个脚本的执行顺序。
  • 适用场景: 独立的脚本(如广告、分析工具),不依赖其他脚本或 DOM。

流程:

  1. HTML 解析时,脚本在后台并行加载。
  2. 一旦脚本加载完成,立即中断 HTML 解析并执行脚本。
  3. 继续解析 HTML。

比较总结

属性加载方式执行时机执行顺序
默认阻塞解析加载后立即执行按文档顺序
defer并行加载HTML 解析完成后执行按文档顺序
async并行加载加载完成后立即执行执行顺序不确定

选择建议

  • 普通 <script>: 需要避免不依赖 DOM 且保证顺序时使用。
  • defer: 适合页面初始化的脚本,推荐在加载外部脚本时使用。
  • async: 适合不依赖其他脚本和 DOM 的独立脚本,比如广告或统计工具。