Reputation: 597
I have been working on adding defer attribute for external scripts used in HEAD section of one of my projects. I had a query on execution order of multiple defer'ed script tags.
Below are my observation which will help us understand my query better:
As per http://www.w3.org/TR/html5/scripting-1.html
the defer attribute is present, then the script is executed when the page has finished parsing
The defer attribute does work. But, I am doubtful on the execution order. It looks like it is different on FF and Chrome.
As per my porject:
<script defer="defer" src="{SERVER_PATH}/deps.js?1441452359"></script>
<script defer="defer" src="{SERVER_PATH}/script1.js?1440067073"></script>
<script defer="defer" src="{SERVER_PATH}/script2.js?1441451916"></script>
Here, deps.js is huge file of around 120kb (gzipped), whereas, script1-3 are of regular size of 20-50kb (gzipped).
On Firefox, execution of defer'ed script does start in order of appearance, but doesn't complete in the same order. Where'as, on chrome unless the previous script completes execution, the next script's execution doesn't start. It looks like Chrome makes sense.
To test the execution order, I had inserted console.log at the first and last line of each scripts, for e.g. in deps.js
console.log("Execution Start: deps");
// minified deps script content.
console.log("Execution End: deps");
Below the console output on Firefox:
Execution Start: deps
Execution Start: script1
Execution Start: script2
// Script Error as script1 needs deps to render completely.
// Script Error as script2 needs deps to render completely.
Execution End: deps
Below the console output on Chrome:
Execution Start: deps
Execution End: deps
Execution Start: script1
Execution End: script1
Execution Start: script2
Execution End: script2
However, behavior on FF is not always as shown above. Sometimes it does work like Chrome. It look like an issue which is Firefox only. Or, may be is it because of the deps.js file being heavy and minified and takes time to render.
Can anyone of similar experience with defer help me? Please let me know, if any other information is needed.
PS: Other solutions like, moving the scripts at the bottom of the page is not something I am looking at this moment.
Upvotes: 33
Views: 13033
Reputation: 1698
Deferred scripts keep their relative order, just like regular scripts.
Consider we have a page with 2 scripts in the following order:
<script defer src="/big.js"></script>
<script defer src="/small.js"></script>
Browsers download those 2 scripts in parallel, but run by the order they go on the page. So big.js
will be executed first despite of that small.js
can be downloaded earlier.
Upvotes: 6
Reputation: 32840
I'd say it's not really possible unless "Execution End" log happens in different event loop than "Execution Start" log.
Can you ensure us on that? As otherwise it will mean that Firefix does some multithreading here, and as we know, there's no support in JS for that.
Upvotes: 1
Reputation: 14423
HTML5.0 spec says this:
If the element has a src attribute, and the element has a defer attribute, and the element has been flagged as "parser-inserted", and the element does not have an async attribute
The element must be added to the end of the list of scripts that will execute when the document has finished parsing associated with the Document of the parser that created the element.
The task that the networking task source places on the task queue once the fetching algorithm has completed must set the element's "ready to be parser-executed" flag. The parser will handle executing the script.
So it does say it defers script execution until the associated Document
is parsed, it also says it's pushed into the list. So the order of the list should be as the script order is being parsed-inserted.
However, the second part kind of worries me. It basically says that it will only be marked for execution until the network task finsihed downloading the script. Then... "parser will handle executing the script".
What I couldn't find in the spec is the case covering script execution after document parsing. Does it keep executing scripts in the list order as they become "ready to be parser-executed"? Or will it wait until all scripts in the list are "ready to be parser executed" then execute them.
Spec (step 15): http://www.w3.org/TR/html5/scripting-1.html#script-processing-src-prepare
Upvotes: 13