标准答案

  1. 浏览器解析 HTML 时会构建 DOM,遇到 CSS、同步脚本和模块脚本时,阻塞点不一样。
  2. CSS 通常不直接阻塞 DOM 解析,但它会阻塞渲染,因为渲染树需要 DOM 和 CSSOM 都准备好。
  3. 如果后面的脚本要读取计算样式,脚本执行还可能等待前面的 CSS 加载完成。
  4. 同步 script 会阻塞 HTML 解析,浏览器要先下载并执行脚本,再继续解析,因为脚本可能读取或修改当前 DOM。
  5. type="module" 默认接近 defer,会按模块依赖图加载,并在文档解析后执行。总结就是:CSS 主要阻塞渲染,同步脚本阻塞解析,模块脚本默认延迟执行。

题目解析

  • CSS:不直接阻塞 DOM 解析,但阻塞渲染;如果后面有脚本要读样式,脚本会等待 CSSOM。
  • 同步脚本:阻塞 HTML 解析,也可能被前面的 CSS 阻塞。
  • defer 脚本:不阻塞 DOM 解析,DOM 解析完成后按顺序执行。
  • 模块脚本:默认延迟执行,依赖模块加载完成后再执行。

首屏关键 CSS 要尽量小,非关键 CSS 可以延后。业务脚本如果不需要阻塞解析,优先使用 defer 或 type="module"。第三方同步脚本要特别谨慎,因为它会拖慢整个解析链路。

代码示例

下面这个同步脚本可能被前面的 CSS 影响,因为脚本可能读取计算样式。

HTML
<link rel="stylesheet" href="/theme.css">
<script>
  const button = document.querySelector('.button')
  console.log(getComputedStyle(button).color)
</script>

常见误区

  • 只说 CSS 不阻塞 DOM 解析,却漏掉它会阻塞渲染。
  • 认为脚本只阻塞自己,不影响 HTML 继续解析。
  • 忽略 CSS 会影响脚本执行,因为脚本可能依赖 CSSOM。

作者信息