Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interaction between jQuery .ready() and <script defer>

I am trying to figure out a problem with some code I have inherited.

I have an HTML page with

<script type="text/javascript" src="file1.js" defer="defer"></script>
<script type="text/javascript" src="file2.js" defer="defer"></script>
</body>
</html>

file1.js has

FOO = {
  init : function () {
    var bar = BAR;
  }
}

$(document).ready(FOO.init);

file2.js has

var BAR = {
}

Because of the defer attribute on the elements, is it safe to assume that when the .ready() calls FOO.init() that BAR may still be undefined at that point b/c the code in file2.js hasn't executed yet because of the deferred execution?

This would match a bug I am trying to track down (only occurs sporadically in IE), but I really want to understand why this is happening before I work on a solution. I have no idea why the original developer used defer, other than a cryptic commend about "he had to" do it this way.

like image 219
mpdonadio Avatar asked Apr 12 '12 15:04

mpdonadio


People also ask

Can I use defer for jQuery?

Deferred() method in JQuery is a function which returns the utility object with methods which can register multiple callbacks to queues. It calls the callback queues, and relay the success or failure state of any synchronous or asynchronous function.

What is the purpose of defer script defer src Myscript JS ></ script?

The defer is a Boolean value, used to indicate that script is executed after the document has been parsed. It works only with external scripts (i.e., works only when we are specifying the src attribute in <script> tag). It declares that the script will not create any content.

What is the difference between script script async and script defer?

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.

What is async and defer in script tag?

Async - means execute code when it is downloaded and do not block DOM construction during downloading process. Defer - means execute code after it's downloaded and browser finished DOM construction and rendering process.


2 Answers

Defer should cause the script to be added to a queue that is processed after the page is completely loaded. According to the spec deferred scripts should be added to the queue in the order they came onto the page.

However different browsers have done slightly different things with the order. IE seems to run defer scripts in the order they finished loading rather than the order they occurred on the page. So you seeing the error sporadically because sometimes it's loading them in the right order and sometimes not.

See this post on hacks.mozilla.com for a more exhaustive explanation and examples of how different browsers handle the ordering of the defer queue.

like image 159
Josh Farneman Avatar answered Sep 22 '22 18:09

Josh Farneman


Deffering in javascript gives preference to the browser of when to interpret the script, in some optimal conditions like with chrome the script is downloaded while the page is being loaded then parsed and interpreted. If you use defer like the above you can never be certain which script is loaded first or when the interpretation is complete.

BAR could be undefined on one page load and be defined on the reload (cached) or the second script was loaded first.

To test this try make a change to one of the scripts to force a new download and interpretation and see what race conditions exist.

like image 27
lukecampbell Avatar answered Sep 23 '22 18:09

lukecampbell