Skip to content

脚本加载:parser-blocking、defer、async 与模块脚本

主题边界

  • 脚本加载涉及 HTML 解析器、预加载扫描器、网络下载和 JS 执行时机。
  • 只说 defer 与 async 的顺序差异不够,还要理解它们为什么影响首屏与事件时序。

机制与流程

  • 普通脚本默认 parser-blocking:HTML 解析遇到 <script> 会暂停,等待脚本下载并执行,再继续解析。
  • defer 脚本可并行下载,但会等到文档解析完成后按出现顺序执行,且通常在 DOMContentLoaded 之前完成。
  • async 脚本并行下载,谁先完成谁先执行,不保证相对顺序;模块脚本默认类似 defer,但依赖图解析和 top-level await 会改变完成时机。

关键差异

  • defer 适合有顺序依赖的初始化脚本;async 适合互不依赖的统计、广告等旁路脚本。
  • type="module" 除了加载时机不同,还引入模块作用域、CORS 获取与依赖图。

边界条件

  • 把所有脚本都加 async 容易打乱初始化顺序,导致运行时竞态。
  • 模块脚本默认严格模式,且跨域获取时遵守更严格的 CORS 规则。

工程落点

  • 脚本标签位置、资源提示、代码分割和 hydration 启动时机都会受加载模型影响。
  • 排查首屏白屏和埋点时序问题时,要先确认脚本是否阻塞了解析或抢占了主线程。

相关主题