3

given I asynchronously(!!) load several JavaScript files with an asynchronous script loader (that writes a script tag into the document's head that then will download the file), are these scripts evaluated in parallel?

<script>
 var script = document.createElement('script');
 script.src = "library1.js";
 document.getElementsByTagName('head')[0].appendChild(script); 
</script>
 <!-- Other Markup -->
<script>
 var script = document.createElement('script');
 script.src = "library2.js";
 document.getElementsByTagName('head')[0].appendChild(script); 
</script>
<!-- Other Markup -->
<script>
 var script = document.createElement('script');
 script.src = "library3.js";
 document.getElementsByTagName('head')[0].appendChild(script); 
</script>

"Normally", when having a standard script tag in the HTML document (body and head!?) the browser will stop/complete all other activites (downloading/page rendering) and only process the single script tag that it encountered. This leads to a "serialized" execution that does not lead to any "race conditions".

But by using the asynchronous loader technique, will the inserted script tag (in the head) also lead (in the end) to a serialized rendering (that when downloaded) only "the current" script will be evaluated or is there the chance that other asynchronously loaded script files will be evaluated in parallel and therefor are prone to race conditions?

Thank you very much!! Tim

Tim
  • 325
  • 3
  • 5

2 Answers2

5

Although scripts will be downloaded in parallel, the order in which they are executed is not deterministic. IE will execute them in the order they finish downloading in, whereas Firefox executes them in the order they are attached in the DOM.

This is a problem. For example, say script A and script B are added using that technique. Now imagine script A is jQuery, and script B does this:

$(document).ready(function(){...})

In IE you're screwed if for whatever reason (eg, network traffic, cache miss) script B finishes downloading before script A, because it will be executed before jQuery has been loaded.

See this article for a better explanation.

As for a solution, you can instead place the <script> elements as far down the page as possible (eg before the closing </body> element. Although this does not guarantee parallel downloads, it does help alleviate the "blocking" problem your solution is addressing.

Crescent Fresh
  • 115,249
  • 25
  • 154
  • 140
  • hello crescent fresh: thank you very much for this excellent and very helpful answer!!!! – Tim Feb 05 '10 at 16:48
  • @Tim: that was a very quick accept, thank you. Just to clarify, by "blocking" I mean "UI blocking". – Crescent Fresh Feb 05 '10 at 16:50
  • maybe just one short question for clarification as you do not mention this explicitly but it sounds like this: Am I right to assume that scripts are then always executed in sequence, never in parallel? thanks – Tim Feb 05 '10 at 16:51
  • I think that if any script has a dependency on another script, you should enforce it in code, that is, use callbacks to run the dependent script when the first has finished. You can also use a tool like RequireJs to enforce dependencies... – opensas Sep 06 '12 at 04:29
  • How to do that without JQuery? – akatran Oct 02 '17 at 10:01
4

As this StackOverflow question says, Javascript is executed by a single thread. Therefore, it's not possible for your scripts to be executed in parallel. As Crescent Fresh's answer notes, you can't rely on the order in which they're executed, but you can rely on one executing completely before the next one starts, as long as nothing in the script does a setTimeout or anything else asynchronous.

Community
  • 1
  • 1
aem
  • 3,896
  • 24
  • 20
  • hello aem, thank you also very much, your answer and the linked question is of great help (and it seems I missed it when searching). Thank you very much!! – Tim Feb 05 '10 at 16:56