Skip to content

脚本加载机制

来源:js/test/ · 配套服务:packages/express/(线上 Cloudflare Worker:express-core-backend)

理解 <script><link> 标签的阻塞行为。演示使用本地延迟服务器(端口 3000)。

启动演示服务

bash
pnpm dev
# 或单独启动:pnpm dev:server

一、Script 阻塞

普通 <script> 阻塞后续 DOM

普通脚本阻塞 HTML 解析器,后续内容必须等脚本加载完才渲染。

<script async> 不阻塞

同样的延迟脚本,加 async 后不阻塞解析,第二个 div 立即渲染。

对比: 同样的 8s 脚本,普通模式阻塞第二个 div 8 秒,async 模式下 div 立即出现。


二、CSS 阻塞

CSS 阻塞渲染(但不阻塞 HTML 解析器继续解析)。

CSS 在 <head> 中 — 阻塞整个 <body> 渲染

CSS 在 <body> 中 — 阻塞后续内容渲染

注意: CSS 不阻塞 HTML 解析(DOM 树正常构建),但阻塞渲染(不会绘制到屏幕)。


三、CSS 与 Script 互相影响

CSS 还会阻塞 <script> 的执行 — 脚本必须等 CSSOM 构建完毕才执行。

即使脚本文件本身很快,只要前面有慢 CSS,脚本就得等 CSS 加载完才执行。


总结

                  阻塞HTML解析    阻塞渲染      执行时机
普通 <script>        ✅            ✅          遇到即执行(阻塞后续一切)
<script async>       ❌            ✅          下载完即执行(不阻塞解析)
<script defer>       ❌            ✅          DOM解析完按序执行
<link stylesheet>    ❌            ✅          阻塞渲染 + 阻塞后续脚本执行