HTML Standard 脚本处理模型详解:async 与 defer 加载顺序、事件循环的完整执行流程
【免费下载链接】htmlHTML Standard项目地址: https://gitcode.com/gh_mirrors/ht/html
在《HTML Standard》规范中,脚本处理模型(script processing model)决定了async与defer脚本的加载顺序和执行时机,并与事件循环(event loop)深度配合:脚本何时下载、何时执行、是否阻塞页面渲染,都由它统一调度。本文用通俗的语言带你走一遍完整流程。
4 种加载模式:一眼看懂脚本处理模型
浏览器解析<script>标签时,会根据是否携带async/defer/type="module"属性,进入 4 种处理模式:
| 模式 | 下载时机 | 执行时机 | 是否阻塞解析 | 执行顺序 |
|---|---|---|---|---|
| 同步脚本(默认) | 立即 | 下载完成后立即执行 | ✅ 是 | 按出现顺序 |
| defer | 立即 | 文档解析完成后、DOMContentLoaded前 | ❌ 否 | 按出现顺序 |
| async | 立即 | 下载完成后立即执行 | ❌ 否 | 谁先下完谁先执行 |
| module | 立即 | 解析完成后执行(隐含 defer) | ❌ 否 | 按出现顺序 |
💡 简单记:defer 排队执行,async 抢跑执行。多个 defer 脚本一定按顺序运行;多个 async 脚本则像赛跑,下载快的先执行。
关于各模式的规范定义,可以在《HTML Standard》规范源文件 source 中检索defer与async属性的小节(该文件共 16 万余行,是 W3C HTML 标准的可编辑源文件)。
事件循环:脚本执行的"总调度台"
很多人把 defer/async 的执行时机和事件循环搞混,其实它们是分层的:
- 脚本处理模型决定"什么时候该执行脚本"(例如 defer 等待解析结束);
- 事件循环决定"脚本在哪个任务里运行"。
事件循环的工作节奏可以概括为四步:
- 取出任务队列中最先到达的任务(task)并执行(脚本执行、事件回调都在这里);
- 更新渲染:处理样式、布局、绘制;
- 执行
requestAnimationFrame回调; - 处理微任务(Promise 回调),清空后再进入下一轮。
因此,即使是 defer 脚本,也要等事件循环到达"执行任务"这一步才会真正运行——这就是为什么 defer 脚本里能拿到已解析完成的 DOM,而 async 脚本可能在 DOM 还没就绪时就执行了。
上图展示了页面 DOM 树中焦点(focus)的传递关系——脚本执行完毕后,事件循环继续驱动焦点、输入等交互行为,脚本模型与页面交互正是通过这套机制衔接起来的。
完整执行流程:从解析到 DOMContentLoaded
把两者串起来,一个含 defer + async 脚本的页面,完整生命周期如下:
- 解析开始:遇到
<script defer>与<script async>,浏览器立刻并行发起下载,解析器继续向下解析 HTML,不被阻塞; - async 脚本下载完成:事件循环收到任务,立即执行(此时 DOM 可能只解析了一半,所以 async 脚本里
document.querySelector可能拿到null); - HTML 解析完成:构建好完整 DOM 树,触发
DOMContentLoaded前的脚本执行窗口; - defer 脚本依次执行:严格按标签出现顺序,全部执行完毕后才派发
DOMContentLoaded事件; - 资源加载完成:图片等加载完毕后触发
load事件,页面正式可交互。
一句话总结:async 拼下载速度,defer 保执行顺序,事件循环负责按轮调度——理解这条主线,就能解释绝大多数"脚本为什么拿不到 DOM""多个脚本顺序错乱"的现场问题。
在真实代码中感受脚本处理模型
本仓库的演示目录里就有脚本加载的实战案例,可以边读边验证:
- 官方规范源文件:source —— W3C HTML 标准全文,包含脚本处理模型、事件循环的完整规范描述
- 多视图器示例(Worker + 动态脚本协作):demos/workers/multiviewer/page.html
- Web Worker 示例(脚本在独立线程中的加载):demos/workers/primes/worker.js
写在最后
脚本处理模型是《HTML Standard》中最贴近日常开发的章节之一:同步脚本保简单、defer 保顺序、async 抢首屏、module 管模块化。配合事件循环的"任务—渲染—微任务"节奏,页面性能优化的 80% 技巧其实都藏在其中。
建议下一步打开仓库中的 source 文件,检索关键词defer、async、event loop,对照本文的流程走读一遍规范原文——你会发现标准比想象中更易读。
【免费下载链接】htmlHTML Standard项目地址: https://gitcode.com/gh_mirrors/ht/html
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考