游乐游手机版
首页/前端开发/文章详情

HTML中script标签如何避免阻塞DOM解析与页面加载

时间:2026-08-17 18:20
在 HTML 页面加载优化中,defer 通常是最稳妥的选择,特别适合需要操作 DOM、并且存在执行顺序依赖的外部脚本;async 更适用于完全独立的脚本,例如统计埋点、监测代码这类场景;而把 放到 前,本质上依然会阻塞页面解析,只是把阻塞发生的时机延后了;默认情况下,普通 script 标签会暂停

在 HTML 页面加载优化中,defer 通常是最稳妥的选择,特别适合需要操作 DOM、并且存在执行顺序依赖的外部脚本;async 更适用于完全独立的脚本,例如统计埋点、监测代码这类场景;而把

  • ❌ 无效:(内联脚本上的 defer 会被忽略)
  • ❌ 无效:defer 属于布尔属性,不接受值)
  • ❌ 无效:(当 asyncdefer 同时存在时,defer 会被忽略)
  • ⚠️ 构建工具(例如 Vite)在开启 build.inlineDynamicImports: true 后,可能会把外部脚本打包成内联代码 → 此时 defer 会彻底失效,因此必须检查最终产出的 HTML
  • async 和 defer 执行时机差异很关键

    async 脚本只要下载完成,就会立刻执行,不会等待 DOM 是否构建完成;而 defer 则不同,它会稳定地等到 DOM 树构建完成后,再在 DOMContentLoaded 事件触发之前执行。这个执行时机的差别非常重要,很多前端页面脚本是否安全运行,往往就取决于这几毫秒之间的时序差异,尤其会直接影响 document.getElementByIdgetElementsByClassName 等 DOM 查询方法能否正常拿到目标元素。

    • async 适合:Google Analytics、百度统计、广告 SDK 等完全独立、不操作 DOM、也不依赖其他脚本的代码
    • defer 适合:核心业务逻辑、UI 组件初始化、需要读取 data- 属性或绑定事件的脚本
    • 多个 async 脚本的执行顺序不可预测,而 defer 会严格按照 HTML 中的书写顺序依次执行
    • type="module" 脚本默认自带类似 defer 的行为,因此再额外添加 defer 也不会产生效果
    • document.write()deferasync 脚本中可能清空整个文档,必须避免使用

    动态创建 script 标签更可控但要自己兜底

    通过 JavaScript 动态创建