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.
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
).
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. 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).
This is the HTML code that I used for the test:
<!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:
console.log("async");
And the content of 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:
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; for IE, the console was async then defer]
Defer.js executes before async.js. But it could be because async.js is placed later in the code, so let's swap them.
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; for IE, the console was async then defer]
Defer.js still executes before async.js, even if async.js has been called before. 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).
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
defer
scripts run without waiting for theasync
scripts to load. – Alvaro Montoro