简体   繁体   English

可以 HTML<script defer> execute before <script async>?

[英]Can HTML <script defer> execute before <script async>?

I'm asking a question on a subject that has been well explored and there are many near-answers to what I am asking, but I haven't been able to find the exact answer to what is a simple question.我在问一个已经深入探讨过的主题的问题,并且我所问的问题有很多接近答案,但我无法找到一个简单问题的确切答案。

I understand that defer scripts run in the order they appear on the page, but only after the DOM has been built, and I get that async scripts run as soon as is possible, and I know that neither one blocks the HTML parser.我知道延迟脚本按照它们出现在页面上的顺序运行,但只有在构建 DOM 之后,我才能尽快运行异步脚本,而且我知道没有人会阻止 HTML 解析器。

Here's the question: Is there a case in which a defer script can execute before all the async scripts have executed?问题是:是否存在延迟脚本可以在所有异步脚本执行之前执行的情况? Essentially, if the HTML parser has parsed the entire document and is ready to run the defer scripts BUT there are still some async scripts that have not loaded yet, will it wait for these async scripts to load (and execute), or will it run the defer scripts?本质上,如果 HTML 解析器已经解析了整个文档并准备运行延迟脚本,但是仍然有一些异步脚本尚未加载,它会等待这些异步脚本加载(和执行),还是会运行延迟脚本?

Thanks!谢谢!

From a really simple test, it seems that the defer does not wait for the async scripts to load... but (there's always a but) it also seems that it depends on the browser. 从一个非常简单的测试,似乎defer不等待async脚本加载...但(总是有一个但是)它似乎也取决于浏览器。

I ran tests on Chrome 41, Firefox 36 and Internet Explorer 11, and got the same results for Chrome and FF (with defer executing before async ) but different results on IE ( async always executed before defer ). 我在Chrome 41,Firefox 36和Internet Explorer 11上运行测试,并获得了与Chrome和FF相同的结果(在async之前执行defer )但IE上的结果不同( async始终在defer之前执行)。

That could be explained if IE was ignoring the async attribute (parsing and executing the code immediately), but according to W3Schools and MDN , async is supported from IE10. 如果IE忽略了async属性(立即解析并执行代码),可以解释这一点,但根据W3SchoolsMDN ,IE10支持async So I guess, that IE process the asynchronous calls in a different way from the other browsers, making it load and execute faster/before the whole page is parsed (then running before the deferred script). 所以我想,IE以与其他浏览器不同的方式处理异步调用,使其在整个页面被解析之前加载和执行得更快(然后在延迟脚本之前运行)。

This is the HTML code that I used for the test: 这是我用于测试的HTML代码:

<!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>

Now the content of async.js: 现在async.js的内容:

console.log("async");

And the content of defer.js: 和defer.js的内容:

console.log("defer");

If I run it "as is", the console result is: 如果我“按原样”运行它,控制台结果是:

async 异步
defer 延缓

That is expected because the scripts are executed immediately before the browser continues parsing the page. 这是预期的,因为脚本在浏览器继续解析页面之前立即执行。

Now let's play with async and defer , and see the results: 现在让我们玩asyncdefer ,看看结果:


Code: 码:

<script type="text/javascript" src="./defer.js" defer></script>
<script type="text/javascript" src="./async.js" async></script>

Result: 结果:

defer 延缓
async 异步

[Note: this was the result on Chrome and Firefox; [注意:这是Chrome和Firefox上的结果; for IE, the console was async then defer] 对于IE,控制台是异步然后推迟]

Defer.js executes before async.js. Defer.js在async.js之前执行。 But it could be because async.js is placed later in the code, so let's swap them. 但这可能是因为async.js稍后放在代码中,所以让我们交换它们。


Code: 码:

<script type="text/javascript" src="./async.js" async></script>
<script type="text/javascript" src="./defer.js" defer></script>

Result: 结果:

defer 延缓
async 异步

[Note: this was the result on Chrome and Firefox; [注意:这是Chrome和Firefox上的结果; for IE, the console was async then defer] 对于IE,控制台是异步然后推迟]

Defer.js still executes before async.js, even if async.js has been called before. Defer.js仍然在async.js之前执行,即使之前已经调用了async.js。 So answering your question: Yes, there are cases in which a deferred script will execute before all asynchronous scripts are loaded and parsed. 回答你的问题: 是的,有些情况下,在加载和解析所有异步脚本之前,将执行延迟脚本


Code: 码:

<script type="text/javascript" src="./async.js"></script>
<script type="text/javascript" src="./defer.js" defer></script>

or 要么

<script type="text/javascript" src="./defer.js" defer></script>
<script type="text/javascript" src="./async.js"></script>

Result: 结果:

async 异步
defer 延缓

This result is expected as in this case async.js is executed immediately, and defer waits for the page to parse (we'll get the same result even if we swap the script position). 这个结果是预期的,因为在这种情况下async.js立即执行,并且延迟等待页面解析(即使我们交换script位置,我们也会得到相同的结果)。


And finally testing an asynchronous script called before one without async/defer (no need to test the other way around, because it would execute immediately, before the call to the async): 最后测试一个在没有异步/延迟的情况下调用的异步脚本(不需要另外测试,因为它会在调用异步之前立即执行):

Code: 码:

<script type="text/javascript" src="./async.js" async></script>
<script type="text/javascript" src="./defer.js"></script>

Result: 结果:

defer 延缓
async 异步

Yes, it is in theory possible for a script with an async attribute to execute after a script with a defer script.是的,理论上可以在带有defer脚本的脚本之后执行带有async属性的脚本。 You should program your scripts accordingly.您应该相应地编写脚本。

Even if that doesn't happen in practise, you should still program your scripts with this expectation, as the spec does not guarantee that async scripts will execute after defer scripts, and so browsers are free to implement the execution that way.即使在实践中不会发生这种情况,您仍然应该按照这种期望来编写脚本,因为规范不保证async脚本会在defer脚本之后执行,因此浏览器可以自由地以这种方式实现执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM