我可以写下以下内容:
<script src="file1.js" defer></script>
<script src="file2.js" defer></script>
<script src="file3.js" defer></script>
这意味着文件可以并行下载,但只能一个接一个地执行。但是,我可以添加async
属性以允许浏览器以随机顺序执行代码。
<script src="file1.js" async></script>
<script src="file2.js" async></script>
<script src="file3.js" async></script>
如果我对性能提升感兴趣,可以更快地执行第二个块吗?正如我所看到的,如果浏览器在一个线程中执行所有JavaScript,那么3个脚本的总执行时间与第一个块没有区别,只有执行顺序可能不同。我是对的吗?
答案 0 :(得分:6)
如果我对性能提升感兴趣,可以更快地执行第二个块吗?
由于脚本将被异步下载和执行,是的,它将减少页面加载时间。
Script-injected "async scripts" considered harmful的作者比较了三种包含脚本的方法:注入脚本,阻止脚本和带有async
属性的脚本。结果是:
script execution onload
----------------- ------------------ --------
script-injected ~3.7s ~3.7s
blocking script ~2.7s ~2.7s
async attribute ~1.7s ~2.7s
如您所见,async
属性可提供最佳性能。如果脚本执行顺序无关紧要,那么你一定要使用它。
关于你的标题问题:
浏览器是否在单个线程中执行加载的脚本?
是的,因为JavaScript是单线程的,但在性能方面无关紧要。下载脚本比实际执行脚本需要更长的时间,因此您应该专注于优化下载部分。
我做了一个测试。我创建了一个简单的脚本:
for (var i = 0; i < 1e8; i++);
我将相同的脚本放在两个文件test1.js
和test2.js
中。然后我制作了两个HTML文件,第一个没有async
,第二个有:
test1.html
:
<!DOCTYPE html>
<script src="test1.js"></script>
<script src="test2.js"></script>
test2.html
:
<!DOCTYPE html>
<script src="test1.js" async></script>
<script src="test2.js" async></script>
然后我在浏览器中打开了这些HTML文件,并在Chrome DevTools中选中了Timeline选项卡:
test1.html
:
test2.html
:
如您所见,在这两种情况下,脚本都不会异步执行。