使用 加载外部 JS 时,浏览器会阻塞 HTML 解析并立即执行;应将脚本置于 前、或加 defer(保证顺序)/async(无序),注意路径以 HTML 文件为基准,加载失败需手动监听 error 事件。

用 <script src></script> 加载外部 JS 文件,必须放在 HTML 解析流程里考虑顺序
浏览器遇到 很多人以为 没加任何属性的 实际项目中,如果模块有依赖关系(比如 jQuery → 插件),别图省事全加 <script src="xxx.js"></script> 时会暂停 HTML 解析,立即下载、编译并执行该 JS 文件。这意味着:如果脚本依赖 DOM 元素(比如想 document.getElementById 某个 <script></script> 又写在 里,大概率报 Cannot read property 'xxx' of null。
<script src></script> 放在 闭合标签前defer 属性(仅适用于外部脚本):<script src="app.js" defer></script>,它会让脚本等 HTML 解析完再按顺序执行async 也行,但执行时机不可控,适合无依赖的分析统计类脚本
src 路径写错是 404 的主因,相对路径以 HTML 文件位置为基准src="js/main.js" 是相对于当前 JS 文件位置,其实不是——它是相对于当前 HTML 文件的 URL。比如 HTML 在 /user/profile.html,那 src="js/main.js" 实际请求的是 /user/js/main.js,而不是 /js/main.js。
src="/static/js/utils.js"(开头带 / 表示从根目录开始)../ 嵌套太多层,容易在页面路由变化时失效加载失败时没有默认提示,得靠
onerror 或 addEventListener('error') 捕获<script src></script> 加载失败(如 404、跨域、网络中断)不会抛 JS 异常,也不会中断后续脚本,但目标文件里的逻辑完全不会运行,且静默失败。
<script src="missing.js" onerror="console.error('JS load failed')"></script>
const s = document.createElement('script');<br>s.src = '/assets/logic.js';<br>s.addEventListener('error', () => console.warn('logic.js failed'));<br>document.head.appendChild(s);
onerror 只对当前 <script></script> 生效;动态创建的 script 才能灵活处理失败逻辑多个
<script src></script> 的执行顺序受 defer/async 和位置共同影响<script src></script> 是“阻塞 + 顺序执行”,但一旦混用 defer 和 async,行为就容易混乱。比如:
<script src="a.js"></script> 和 <script src="b.js" defer></script>:a.js 立即执行,b.js 等 DOM 解析完再执行(且保证在 a.js 之后,因为 defer 脚本按出现顺序执行)<script src="c.js" async></script> 和 <script src="d.js" async></script>:谁先下载完谁先执行,顺序不确定defer 和 async 时,async 总是优先级更高,可能打断 defer 的顺序保证async,老实用 defer 或手动控制加载链。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











