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.
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.
In practice, defer is used for scripts that need the whole DOM and/or their relative execution order is important. And async is used for independent scripts, like counters or ads. And their relative execution order does not matter.
The defer attribute is a boolean attribute. If the defer attribute is set, it specifies that the script is downloaded in parallel to parsing the page, and executed after the page has finished parsing. Note: The defer attribute is only for external scripts (should only be used if the src attribute is present).
defer. This Boolean attribute is set to indicate to a browser that the script is meant to be executed after the document has been parsed, but before firing DOMContentLoaded . Scripts with the defer attribute will prevent the DOMContentLoaded event from firing until the script has loaded and finished evaluating.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With