HTML中的脚本加载

浏览器中 script、defer、async 与模块脚本的加载方式。

#type / concept #status / growing #resource / html #resource / javascript #platform / browser

[!info] related notes

HTML中的脚本加载

这篇笔记关注浏览器脚本加载层,不讨论 ECMAScript 语法本身。

三种加载模式

普通 script

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

浏览器遇到时会:停止解析 → 下载 → 执行 → 继续解析。这叫解析阻塞,因为 JS 可能修改 DOM。

defer

<script src="app.js" defer></script>
  • 脚本并行下载
  • HTML 继续解析
  • 等 HTML 全部解析完成后再按顺序执行
  • 适合依赖 DOM 的页面脚本

async

<script src="app.js" async></script>
  • 脚本并行下载
  • 下载完立刻执行,执行时可能打断 HTML 解析
  • 多个 async 脚本执行顺序不保证

模块脚本

<script type="module" src="./main.js"></script>
  • 默认延迟执行
  • 顶层 this 不是 window
  • 默认严格模式
  • 变量不会污染全局
  • 支持 import/export

速查对比

类型下载执行时机阻塞解析顺序保证
普通阻塞立即
defer并行DOM 解析完
async并行下载完立即可能打断不保证
module并行默认延迟

重点问题

  • 普通 <script> 如何阻塞解析
  • deferasync 的区别
  • type="module" 为什么改变脚本加载与作用域方式
  • 动态插入脚本有什么行为差异

面试要点

来自 defer-vs-async-interview-question 的面试视角整理。

一句话回答

deferasync 都能让脚本并行下载,但 defer 会等 HTML 解析完成后按顺序执行,async 则是下载完就立刻执行,顺序不保证。

最稳的回答主线

defer

  • 并行下载
  • 不阻塞 HTML 继续解析
  • DOM 解析完成后再执行
  • 多个 defer 脚本顺序可控

async

  • 并行下载
  • 谁先下完谁先执行
  • 执行时可能打断 HTML 解析
  • 多个脚本执行顺序不保证

场景化表达

  • 依赖 DOM 或多个脚本有先后关系时,优先考虑 defer
  • 独立统计脚本、广告脚本这类互不依赖脚本,更常见 async

最短记忆方式

defer 是延后且有序,async 是谁快谁先执行。

放回主题图里看

创建于 2025/1/1 更新于 2026/5/27