在前端开发内容学习中,HTML中script标签在页面加载时如何避免阻塞网页DOM解析是常见主题。很多人在阅读时会遇到概念分散、步骤不清和注意点难以归纳的问题。本文按照基础概念、操作流程和关键细节,对相关内容进行整理。
defer最稳妥,适用于需操作DOM且有顺序依赖的外部脚本;async适合完全独立脚本如统计埋点;script放/body前仍阻塞解析,仅推迟阻塞点;默认script会暂停DOM构建直至下载执行完成。
直接加 defer 是最稳妥的选择,前提是脚本是外部的、需要操作 DOM、且有执行顺序要求;若脚本完全独立(如统计埋点),用 async 更合适;把 <script> 放到 </body> 前只是“看起来不卡”,但没解决本质问题——它仍会阻塞解析,只是阻塞点挪到了页面末尾。
浏览器是流式解析 HTML 的,遇到没有 defer 或 async 的 <script src="a.js">,会立刻暂停 DOM 构建,发起网络请求,等下载、解析、执行全部完成才继续。哪怕脚本只有一行 console.log,只要它在 <head> 里,<body> 里的文字、按钮、图片就全得等它。
DOMContentLoaded 时间远晚于 first-contentful-paint
document.getElementById(...) is null
<script> 放在 <body> 中间时,后面的 HTML 元素根本不会被解析,直到脚本执行完defer 不是“写了就有用”,它只对满足两个硬条件的外部脚本起作用:必须有 src 属性,且 defer 必须作为无值布尔属性出现。其他任何写法都会静默失效——浏览器既不报错也不提示,你很难从 Network 或 Elements 面板里发现它没起作用。
<script src="utils.js" defer></script>
<script defer>console.log(1)</script>(内联脚本加 defer 被忽略)<script src="a.js" defer="true"></script>(defer 是布尔属性,不认值)<script src="a.js" async defer></script>(async 和 defer 混用,defer 直接被忽略)build.inlineDynamicImports: true 时,可能把外部脚本转成内联 → defer 彻底失效,需检查最终生成的 HTMLasync 脚本下载完立刻执行,不管 DOM 是否构建完成;defer 则一定等到 DOM 树构建完毕、DOMContentLoaded 触发前执行。这个时间差决定了你能不能安全调用 document.getElementById 或 getElementsByClassName。
async 适合:Google Analytics、百度统计、广告 SDK 等完全独立、不操作 DOM、不依赖其他脚本的代码defer 适合:主业务逻辑、UI 组件初始化、需要读取 data- 属性或绑定事件的脚本async 多个脚本执行顺序不确定,defer 严格按 HTML 中书写顺序执行type="module" 脚本默认自带 defer 行为,再加 defer 无效document.write() 在 defer 或 async 脚本中会清空整个文档,必须移除通过 JavaScript 创建 <script> 并插入 document.head 或 document.body,能精确控制加载时机、做错误重试、避免重复加载。但它绕过了预加载扫描器(preload scanner),浏览器无法提前发现并并发拉取资源。
window.myLib 是否已存在再决定是否加载;可监听 load/error 事件做 fallbackconst s = document.createElement('script'); s.src = '/app.js'; s.onload = () => init(); document.head.appendChild(s);
<link rel="stylesheet"> 默认不阻塞渲染,如需阻塞,得用新属性 blocking="render"(目前仅 Chromium 125+ 支持)真正容易被忽略的是:即使用了 defer,脚本执行仍会阻塞 DOMContentLoaded 事件触发;而 async 执行时仍会中断 HTML 解析——它们只是把阻塞点挪了位置,并非“完全不阻塞”。要不要阻塞、在哪阻塞,得根据脚本用途和用户体验目标来权衡,不是套个属性就万事大吉。
tlwdr7650路由器没有wps按钮(tlwdr7650路由器没有wps按钮怎么办)
tlwdr7632扩展器电脑怎么设置(tlwdr7632扩展器电脑设置方法)
tlwda6332re安装教程(tlwda6332re如何安装)
tlwdr7632扩展器手机怎么设置(tlwdr7632扩展器手机设置方法)
tlxdr3010怎么设置网速快(tlxdr3010网速快设置方法)
tlwdr5620易展版怎么克隆(tlwdr5620易展版克隆方法)