浏览器是否在单个线程中执行加载的脚本?

Max*_*kyi 5 html javascript performance asynchronous

我可以写下面的内容:

<script src="file1.js" defer></script>
<script src="file2.js" defer></script>
<script src="file3.js" defer></script>
Run Code Online (Sandbox Code Playgroud)

这意味着文件可以并行下载,但只能一个接一个地执行.但是,我可以添加async属性以允许浏览器以随机顺序执行代码.

<script src="file1.js" async></script>
<script src="file2.js" async></script>
<script src="file3.js" async></script>
Run Code Online (Sandbox Code Playgroud)

如果我对性能提升感兴趣,第二个块可以更快地执行吗?正如我所看到的,如果浏览器在一个线程中执行所有JavaScript,那么3个脚本的总执行时间与第一个块没有区别,只有执行顺序可能不同.我对吗?

Mic*_*ski 6

如果我对性能提升感兴趣,第二个块可以更快地执行吗?

由于脚本将被异步下载和执行,是的,它将减少页面加载时间.

该作者认为是有害的脚本注入的"异步脚本"进行比较,包括剧本的三种方法:注入脚本,阻塞脚本,并用脚本async属性.结果是:

                    script execution   onload  
 ----------------- ------------------ -------- 
  script-injected   ~3.7s              ~3.7s   
  blocking script   ~2.7s              ~2.7s   
  async attribute   ~1.7s              ~2.7s  
Run Code Online (Sandbox Code Playgroud)

如您所见,该async属性提供了最佳性能.如果脚本执行顺序无关紧要,那么你一定要使用它.


至于你的标题问题:

浏览器是否在单个线程中执行加载的脚本?

是的,因为JavaScript是单线程的,但在性能方面并不重要.下载脚本比实际执行脚本需要更长的时间,因此您应该专注于优化下载部分.


我做了一个测试.我创建了一个简单的脚本:

for (var i = 0; i < 1e8; i++);
Run Code Online (Sandbox Code Playgroud)

我将相同的脚本放入两个文件中,test1.js并且test2.js.然后我制作了两个HTML文件,第一个没有async,第二个有:

test1.html:

<!DOCTYPE html>
<script src="test1.js"></script>
<script src="test2.js"></script>
Run Code Online (Sandbox Code Playgroud)

test2.html:

<!DOCTYPE html>
<script src="test1.js" async></script>
<script src="test2.js" async></script>
Run Code Online (Sandbox Code Playgroud)

然后我在浏览器中打开了这些HTML文件,并在Chrome DevTools中选中了Timeline选项卡:

test1.html:

test2.html:

如您所见,在这两种情况下,脚本都不是异步执行的.

另请参见:JavaScript是否保证是单线程的?.