当浏览器遇到脚本标签时,它会呈现页面。

5

阅读完浏览器如何工作和浏览器渲染流程之后,我仍然对当遇到<script>标签时浏览器的解析过程有些困惑,这些文章并没有很好地覆盖这一点。

主要过程如下图所示: enter image description here

假设我们有一个简单的 HTML 页面:

<html>
<head>
<link rel="stylesheet" href="main.css">
<script src="main.js"></script>
<link rel="stylesheet" href="another.css">
</head>
<body>
</body>
</html>

问题:

  1. 浏览器是单线程的,那么HTML解析器和CSS解析器如何并行工作?
  2. 在HTML解析器中,当遇到<script>标签时,浏览器是否会暂停直到JS文件下载并完全执行?例如,在这个例子中,浏览器将不会下载another.css,直到main.js下载并执行完成吗?

“浏览器是单线程的” - 谁说的? - Jonathon Reinhart
关于script标签,浏览器无论在哪里等待它(头部或正文):例如,当它在头部时,浏览器会在呈现正文之前完全停止解析它。 - Maen
@Bigood,那么当解析脚本时,一切都会停止,只是等待它完成吗?任何下载也会停止吗? - jason
@JonathonReinhart,JavaScript 是单线程的,但浏览器不是单线程的,对吗? - jason
1个回答

7

1:浏览器不是单线程的,如果您注意到任务管理器,您会发现浏览器实际上使用了多个线程。我认为浏览器保留了1个线程用于HTML页面,并创建一个新线程/重复使用线程来获取图像、CSS和JS,从而不会阻塞主要的HTML线程。

2:当HTML解析器遇到<script src="main.js"></script>标签时,它会将main.js下载到客户端并执行其中可以找到的任何js代码。

通常最好停止js的执行。这就是为什么您通常将所有js功能放入函数中,并具有初始化或加载函数来触发在HTML页面上的所有元素加载完毕后再执行js。

您可以通过将事件监听器附加到body.onload事件<body onload="load()">,其中load()是您main.js中的一个函数来实现此操作。

请看这个:链接


对于第二个问题,当下载 main.js 并执行代码时,其他所有事情都会停止吗?浏览器不会在 main.js 执行之前下载 another.css 吗?如果是这样的话,有什么工具可以观察吗? - jason
处理main.js的线程会一直执行,直到完成当前任务。其他需要下载的元素,例如another.css,将被另一个线程处理,不会阻塞html或js的执行。这也是为什么你会想在body onload事件上执行js的原因。至于工具,如果你使用Chrome,可以按Ctrl+Shift+I查看网络流量,并选择Network选项卡。在这里,你会发现有几个请求(线程)同时运行。 - Raveno

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接