Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

defer scripts and execution order on browsers

Tags:

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.

like image 958
Bijoy Anupam Avatar asked Sep 05 '15 12:09

Bijoy Anupam


People also ask

Do deferred scripts run in order?

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.

Does the async and defer are same in nature of executing the scripts in browser?

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.

How do you defer a script in HTML?

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).

What does it mean to defer a script?

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.


1 Answers

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

like image 194
MinusFour Avatar answered Sep 23 '22 02:09

MinusFour