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

Critical Rendering Path理论与Chrome实际渲染行为不符的技术问询

关于关键渲染路径(Critical Rendering Path)的实际表现疑问

我正在编写一个关键渲染路径工作原理的示例,代码如下:

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Document</title>
  </head>
  <body>
    <div>1</div>
    <style>
      body {
        background-color: green !important;
      }
    </style>
    <script src="./test.js"></script>
    <div>2</div>
    <script src="./test2.js"></script>
    <div>3</div>
  </body>
</html>

test.js

alert('test')

test2.js

alert('test 2')

这些脚本下载完成后会立即执行,无需等待onload事件。

我原本认为浏览器加载该HTML时,会先弹出两个alert,此时UI无任何渲染内容,但实际表现是:

  • 第一个alert弹出时,UI显示绿色背景与数字1
  • 第二个alert弹出时,仅显示数字1

我的疑问:

  1. 为何浏览器能在所有脚本执行完成前渲染UI内容?
  2. HTML解析器是否逐行工作?两次alert间的UI状态存在差异。
  3. 若逐行解析,为何第二个alert弹出时仅渲染了数字1,而非1、2或1、2、3?

我使用Chrome测试,根据关键渲染路径理论,JS会阻塞解析与渲染,预期alert关闭前UI无内容,但实际与理论不符,特此问询。


问题解答

1. 为何脚本执行前会出现渲染内容?

关键渲染路径中JS确实会阻塞解析,但浏览器在遇到阻塞脚本前,会先把已解析完成的DOM和CSSOM合并成渲染树,触发一次渲染。你的代码里,在第一个<script>标签前,浏览器已经解析了<div>1</div>和内嵌的<style>,此时DOM和CSSOM都已准备就绪,浏览器会先完成这次渲染,再去下载执行test.js——这就是第一个alert弹出时能看到绿色背景和数字1的原因。

2. HTML解析器是逐行工作的吗?

是的,HTML解析器采用流式逐行解析的方式,遇到标签就逐步构建DOM树。两次alert的UI差异,正是因为解析到不同阶段就被脚本阻塞导致的。

3. 第二个alert为何只显示数字1?

当浏览器解析到第一个<script>时,会暂停解析流程,先下载并执行test.js。此时<div>2</div>还未被解析,自然不会出现在DOM中。等你关闭第一个alert,浏览器才会继续解析到<div>2</div>,随后又遇到第二个<script>,再次暂停解析去下载执行test2.js——这里的核心是:脚本执行前,浏览器不会自动触发新的渲染。也就是说,解析完<div>2</div>后,还没来得及生成新的渲染树并完成渲染,就被test2.js的alert阻塞了,所以此时UI仍停留在之前的状态,只显示数字1。

补充说明:JS阻塞解析是为了避免脚本操作尚未解析的DOM节点,但浏览器会在阻塞前完成已就绪内容的渲染,这是浏览器的体验优化行为,保证用户能尽早看到页面内容。


内容的提问来源于stack exchange,提问作者Dung Nguyen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 21:59:52