You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular带defer属性的脚本包为何被放置在body末尾而非head中

Angular将带defer属性的脚本包放在body末尾的原因

很多人会觉得既然defer属性本身已经实现了「不阻塞HTML解析、DOM解析完成后按顺序执行脚本」的效果,放head和放body没有区别,实际上Angular CLI选择这个放置策略是实打实的工程化考量,不存在冗余设计:

  • 对老旧浏览器做行为兜底
    并不是所有浏览器都正确实现了defer属性:部分早期浏览器(比如IE8及更早版本、部分老旧移动端浏览器)要么完全不识别defer属性,要么对defer的执行时序实现有bug。如果把带defer的脚本放在head里,在不支持defer的浏览器中,脚本会变成同步阻塞脚本,立刻中断HTML解析执行,直接导致长时间白屏甚至脚本报错。而把脚本放在</body>闭合标签之前的位置,不管浏览器是否支持defer,脚本都天然会在整个DOM结构解析完成后才执行,和defer的预期行为完全对齐,不需要额外做兼容性判断就能覆盖所有用户场景。
  • 彻底规避脚本执行时序风险
    Angular应用启动的前提是页面中已经存在应用根节点(默认是<app-root>元素)。按照规范defer脚本会在DOM解析完成、DOMContentLoaded事件触发前执行,但在部分浏览器的历史实现中,放在head中的defer脚本存在提前执行的偶发bug,如果脚本执行时根节点还没被解析出来,Angular会直接因为找不到挂载点抛出致命错误,应用完全无法启动。把脚本放在body末尾,意味着所有DOM元素(包括应用根节点)都已经完成解析,从物理位置上就保证了脚本执行时依赖的DOM节点一定存在,从根源上避免了这类时序bug。
  • 不会损失加载性能,反而能优化关键资源优先级
    现代浏览器都内置了预加载扫描器,会在HTML解析的最早期阶段就遍历整个文档识别需要加载的静态资源,不管脚本放在head还是body末尾,带defer的脚本都会被预加载扫描器提前捕获,和其他资源并行加载,不会因为位置靠后就延后加载开始的时间。相反,把脚本放在body末尾,不会在HTML解析的初始阶段和head中的关键首屏资源(CSS样式表、首屏字体、meta配置等)抢网络带宽和连接优先级,能让首屏渲染必需的CSS等资源更快加载完成,缩短首次内容绘制时间。

简单来说,这种写法不是多此一举,是前端工程里经过海量场景验证的「防御性编程」实践,用几乎零成本的位置调整,换来了更好的兼容性和稳定性。

Angular构建生成的index.html示例截图

内容的提问来源于stack exchange,提问作者Hassan Arafat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 10:15:31