defer仅对带src的外部脚本生效,执行时机固定在DOM构建完成、DOMContentLoaded之前,按HTML顺序执行,不支持内联脚本,混用async会忽略defer,且无法拦截运行时错误。

defer 不是“加了就自动延迟执行”的万能开关,它只对带 src 的外部脚本生效,且执行时机严格固定在 DOM 构建完成、DOMContentLoaded 之前——这意味着你能在脚本里直接操作 document.body 或 document.getElementById,但不能指望它等图片或 CSS 加载完。
defer 只对外部脚本(src)有效
浏览器会完全忽略内联脚本上的 defer 属性,既不报错也不延迟:
- ❌
<script defer>init();</script>——init()会在 HTML 解析到此处时立即执行(等同于无属性) - ✅
<script src="main.js" defer></script>—— 下载异步,执行推迟到 DOM 就绪后 - ⚠️
<script src="utils.js" defer></script>——defer是布尔属性,赋值会被忽略,实际仍生效
多个 defer 脚本按 HTML 顺序执行,但依赖链必须写对
执行顺序保序 ≠ 加载顺序保序,更不等于逻辑依赖自动满足。如果 app.js 依赖 lodash.js,但 HTML 中 app.js 写在前面,就会报 ReferenceError: _ is not defined:
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
- ✅ 正确顺序:
<script src="lodash.js" defer></script>→<script src="app.js" defer></script> - ❌ 错误顺序:
<script src="app.js" defer></script>→<script src="lodash.js" defer></script> - ⚠️ 混用
async和defer:浏览器以async为准,defer被静默丢弃,执行可能穿插进 defer 队列中间
defer 脚本里不能用 document.write
哪怕 DOM 已就绪,document.write 在 defer 脚本中也会被浏览器直接忽略,或触发严重错误(如清空整个页面),现代代码基本不用,但老项目迁移时容易踩坑:
- ❌
<script src="legacy.js" defer></script>中含document.write('<div>...</div>')→ 页面异常或控制台报错 - ✅ 替代方案:用
document.body.insertAdjacentHTML或document.createElement+appendChild - ⚠️ 注意:服务端注入的初始化数据(如
window.__INITIAL_STATE__)必须放在所有defer脚本之前,且自身不能加defer,否则defer脚本读不到
真正容易被忽略的是:defer 只管“什么时候执行”,不管“执行成不成”。路径 404、CSP 阻断、模块内部动态 import() 失败,都不会被 defer 拦住或重试——这些得靠运行时错误捕获和 fallback 逻辑兜底。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










