Skip to content

defer 与 async

字数: 0 字 时长: 0 分钟


一、作用总览

属性本质核心目标
defer / asyncHTML 元素属性(attribute)让外部脚本不再阻塞 HTML 解析,提升加载性能

二、运行机制对比

维度deferasync
下载过程并行下载,不阻塞 DOM 构建并行下载,不阻塞 DOM 构建
执行时机DOM 构建完成后、DOMContentLoaded 事件 下载完立即执行,与 DOM 是否完成无关
执行顺序按文档出现顺序依次执行谁先下载完谁先执行,无顺序保证
是否阻塞渲染执行时不阻塞(因 DOM 已构建完)执行时会阻塞 HTML 解析(瞬间暂停)

三、典型场景速查

场景推荐属性原因
需操作 DOM 的业务代码deferDOM 已构建,安全操作
多脚本有依赖关系defer保证顺序
第三方统计 / 广告async独立、无依赖、越早越好
对渲染顺序敏感的资源不用 async避免不可预期的执行点

四、工程实践提示

  1. 现代构建工具(Webpack / Vite)已自动为 chunk 加 defer,无需手动干预。
  2. 手动优化点
    • Google Analytics 等统计代码 → 官方默认 async
    • 广告追踪脚本 → 通常 async,若依赖 DOM 可改 defer
  3. 脚本位置
    • defer 脚本→直接放 <head>,可尽早启动下载。
    • async 脚本→推荐 </body> 前,降低阻塞渲染风险。
  4. 特殊需求 → 用 <link rel="preload"> 提前拉高下载优先级,再按场景选 deferasync

五、defer 细节补充

  1. 告诉浏览器:继续解析 HTML,别等脚本下载。
  2. 下载完成后先待命,直到 DOM Tree 构建完毕。
  3. 总在 DOMContentLoaded 之前按文档顺序执行。
  4. <head><body> 都不影响顺序,只与源码顺序有关。
html
<head>
  <script defer src="a.js"></script>
</head>
<body>
  …大量 HTML…
  <script defer src="b.js"></script>
</body>
<!-- 执行顺序:a.js → b.js,与物理位置无关 -->

六、async 细节补充

1. 下载阶段

  • 独立线程,不阻塞 HTML 解析

2. 执行阶段

  • 下载完立即执行,此时暂停 HTML 解析(瞬间阻塞)。

3. 顺序特性

  • 多个 async 脚本无序;先返回先执行。

4. 对比记忆

对比项结果
vs 普通脚本下载不阻塞解析
vs defer不等待 DOM 完成,执行点不可预期

适用:无依赖、不操作 DOM、越早运行越好的独立模块。
慎用:有执行顺序要求或需访问 DOM 的代码。


alt text

/