我第一次开始学习网络编程...
我了解到,当发现 <script>
时,解析 HTML 线程就会暂停。标记,并在运行脚本后重新启动。所以我用多种方式测试了它,发现了一些难以理解的地方。第一个示例名为 case1.html
正在使用内联脚本标记。另一个叫case2.html
正在使用外部脚本文件(case2.js
)。
案例1.html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Case 1 Ttitle</title>
</head>
<body>
<p>Before external script</p>
<script>
var delay = 5000;
var start = new Date().getTime();
while (new Date().getTime() < start + delay);
</script>
<p>after external script</p>
</body>
</html>
案例2.html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Case 2 Ttitle</title>
</head>
<body>
<p>Before external script</p>
<script src="./case2.js"></script>
<p>after external script</p>
</body>
</html>
case2.js
var delay = 5000;
var start = new Date().getTime();
while (new Date().getTime() < start + delay);
按照我的理解,这两个结果应该是一样的,但是却完全不同。我使用最新版本的 chromium 浏览器进行了测试。
在 case1.html
,一开始什么也没有,五秒后所有文字都被打印出来,如右图所示。
- case 1 result screenshot
(抱歉,我无法发布图片...我使用了链接)
使用开发人员工具,我查看了执行流程:我不知道为什么解析 HTML 会在一个流程中进行,而不会同时中断并运行脚本......并且有两个“绘制”部分(绿色)在五秒评估脚本之后。并重复执行脚本和解析。
在“case2.html”中,脚本前面的句子立即被打印出来,5秒后又打印了另一句话。有两个解析部分:一个位于评估脚本的前面,另一个位于后面。
我知道解析 HTML 线程在找到 <script>
时会暂停。标记,并在运行脚本后重新启动。案例2有道理,但我无法理解案例1的结果...
我的问题是,为什么在情况 1 中解析 HTML 会继续,为什么第一次打印在内联脚本结束后运行?
我已阅读以下内容,但没有得到明确的答案...
- Render blocking Javascript at end of body tag - Firefox renders some visual content, Chrome does not
- Why do inline scripts block rendering when put at the bottom of a page?
- https://developers.google.com/web/tools/lighthouse/audits/blocking-resources
非常感谢您阅读我的问题!
最佳答案
运行脚本时不会发生渲染。
但是在等待获取网络资源时允许渲染。所以在 case2.html
,在 <script>
之前已解析的所有内容标签在等待获取脚本时呈现。然后它会阻止并执行脚本。
关于javascript - 当我使用内联 <script> 标记时,为什么解析 HTML 不会停止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60999653/