
通过 `<script defer>` 属性,可在不阻塞 <a style="color:#f60; text-decoration:underline;" title= "html" href="https://www.php.cn/zt/15763.html" target="_blank">html 解析的前提下并行下载多个脚本,并严格按声明顺序执行,完美解决“<a style="color:#f60; text-decoration:underline;" title= "异步加载" href="https://www.php.cn/zt/34044.html" target="_blank">异步加载但顺序执行”的需求。</script>
在现代 Web 开发中,我们常面临一个经典权衡:既要提升资源加载性能(如并行下载脚本),又要确保运行时依赖正确(如 two.js 必须在 one.js 初始化完成后执行)。手动用 fetch + eval 实现虽可行,但存在严重安全隐患(eval 执行任意字符串代码易引发 XSS)、缺乏错误处理、无法利用浏览器缓存与预加载优化,且违背模块化设计原则。
推荐的标准化解决方案是使用 HTML <script> 标签的 defer 属性:
<script defer src="one.js"></script> <script defer src="two.js"></script>
✅ 工作原理:
- 浏览器在解析 HTML 时立即发起两个脚本的并行 HTTP 请求(不阻塞 DOM 构建);
- 脚本下载完成后暂存于内存,不立即执行;
- 待整个 HTML 解析完成、DOM 构建完毕(即触发 DOMContentLoaded 事件前),按标签出现顺序依次同步执行 —— 因此 one.js 总在 two.js 之前运行。
⚠️ 注意事项:
立即学习“Java免费学习笔记(深入)”;
- defer 仅对外部脚本(带 src 属性)生效,内联脚本忽略该属性;
- 不可与 async 同时使用(二者行为冲突,async 会忽略 defer);
- 脚本必须位于 <head> 或 <body> 中(无需等待 </body>),但不能在 document.write() 动态插入的 script 上生效;
- 若需更精细控制(如动态加载、条件执行或 ES 模块依赖),应优先考虑 import() 动态导入:
// 在需要时按序加载并执行
await import('./one.js');
await import('./two.js'); // 确保 one.js 的副作用/导出已就绪总结:<script defer> 是语义清晰、安全高效、广泛兼容(IE10+)的标准方案,应作为“并行加载 + 顺序执行”场景的首选;避免 eval、setTimeout 轮询或手动状态管理等非标准做法,兼顾性能、可维护性与安全性。










