我正在就一个经过深入探讨的主题提出一个问题,并且我的问题有很多接近答案,但我无法找到一个简单问题的确切答案。 / p>
我理解延迟脚本按照它们在页面上出现的顺序运行,但只有在构建DOM之后才会运行,并且我会尽快运行异步脚本,并且我知道没有人阻止HTML解析器
这是一个问题:在所有异步脚本执行之前,是否存在延迟脚本可以执行的情况?基本上,如果HTML解析器已解析整个文档并准备运行延迟脚本但仍有一些尚未加载的异步脚本,它是否会等待这些异步脚本加载(和执行),或者它是否会运行推迟脚本?
谢谢!
答案 0 :(得分:5)
从一个非常简单的测试来看,似乎defer
不等待async
脚本加载......但是(总是有一个但是)它似乎依赖于浏览器
我在Chrome 41,Firefox 36和Internet Explorer 11上运行测试,并获得了与Chrome和FF相同的结果(defer
之前执行async
)但IE上的结果不同{{1始终在async
之前执行。
如果IE忽略defer
属性(立即解析并执行代码),可以解释这一点,但根据W3Schools和MDN,async
支持IE10。所以我想,IE以与其他浏览器不同的方式处理异步调用,使其在整个页面被解析之前加载并执行得更快(然后在延迟脚本之前运行)。
这是我用于测试的HTML代码:
async
现在async.js的内容:
<!doctype html>
<html>
<head>
<title>Test</title>
<script type="text/javascript" src="./async.js"></script>
<script type="text/javascript" src="./defer.js"></script>
</head>
<body>
Testing
</body>
</html>
defer.js的内容:
console.log("async");
如果我按“原样”运行它,控制台结果为:
异步
延迟
这是预期的,因为脚本会在浏览器继续解析页面之前立即执行。
现在让我们玩console.log("defer");
和async
,看看结果:
<强>代码:强>
defer
<强>结果:强>
延迟
异步
[注意:这是Chrome和Firefox上的结果;对于IE,控制台是异步然后推迟]
Defer.js在async.js之前执行。但这可能是因为async.js稍后放在代码中,所以让我们交换它们。
<强>代码:强>
<script type="text/javascript" src="./defer.js" defer></script>
<script type="text/javascript" src="./async.js" async></script>
<强>结果:强>
延迟
异步
[注意:这是Chrome和Firefox上的结果;对于IE,控制台是异步然后推迟]
Defer.js仍然在async.js之前执行,即使之前已经调用了async.js。所以回答你的问题:是的,有些情况下,在加载和解析所有异步脚本之前,将执行延迟脚本。
<强>代码:强>
<script type="text/javascript" src="./async.js" async></script>
<script type="text/javascript" src="./defer.js" defer></script>
或
<script type="text/javascript" src="./async.js"></script>
<script type="text/javascript" src="./defer.js" defer></script>
<强>结果:强>
异步
推迟
这个结果是预期的,因为在这种情况下async.js立即执行,并且defer等待页面解析(即使我们交换<script type="text/javascript" src="./defer.js" defer></script>
<script type="text/javascript" src="./async.js"></script>
位置,我们也会得到相同的结果)。
最后测试一个在没有异步/延迟的情况下调用的异步脚本(不需要另外测试,因为它会在调用异步之前立即执行):
<强>代码:强>
script
<强>结果:强>
延迟
异步