22

I have some confusion around the new async attribute to the script element in HTML5 that I hope someone can give a clear answer to.

Browsers are capable of Parallel Connections, therefore images will be downloaded in parallel. But any external javascript is not downloaded in parallel with other external javascript and images. Scripts block page loading until they have been downloaded and executed.

To download a script without blocking the rest of the page loading, the most common technique is to create a script element, like Google Analytics snippet does:

var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.src = '...ga.js';
ga.async = true;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);

I'm not sure of how that works exactly - either

  • the browser parses and renders the page, then once it has finished it notices the DOM has changed, resulting in the ga.js script being downloaded and executed

or

  • the browser starts downloading the javascript in parallel with other resources.

I think it is the latter.

The new asynchronous Google Analytics snippet includes the HTML5 async attribute in the script element it creates. That will not help the page blocking problem - that has already been solved by the "Script DOM Element" technique. So what does async add to the picture? According to w3schools, "if async is present, the script is executed asynchronously with the rest of the page (the script will be executed while the page continues the parsing)".

And according to Steve Souders site, "the main benefit of this [async attribute] is it tells the browser that subsequent scripts can be executed immediately – they don’t have to wait for ga.js".

So are async and the Script DOM element technique both solving the same problem?

6 Answers 6

12

Will work:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>$('body').append('Yey');</script>

Will not work:

<script async src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>$('body').append('Yey');</script>
Sign up to request clarification or add additional context in comments.

2 Comments

Yeah, I find little people talking about this... you have to use the onload="blah()" attribute to do your init after the script downloads, or otherwise just put the init code at the end of the script itself (don't rely on traditional $(document).ready() though, cause that won't work anymore)
Very well boiled down the issue! — I would stress, that while 2nd is certain to not work, 1st is not certain to wor. Just expressing an intent, that this is what's desired... (in practice of course wrapping any dom manip in a DOM-ready event...)
9

The async attribute is just a clearer (no ambiguity very straightforward) and cleaner (it will, or is already, part of the respected HTML5 specification) approach to solve the problem. If your site serves scripts from another domain (or CDN) then the async attribute gives you a little reliability (allow the user to at least read the static content) in that the page won't block while a script from a slow (possibly down) remote host is trying to load.

4 Comments

Hi. Thanks for replying. I think you are agreeing that there is no difference? That's the conclusion I came to, but I noticed that this post from the respected Steve Souders which suggests that there is a distinct benefit from using the async tag over and above the Script DOM element technique link.
@user265330 - the article is from 2009 and doesn't mention the ASYNC attribute on script tags.
Yes, it does. Under 'The Async snippet', the code uses setAttribute to set async (ok, not the way it's done in the latest ga snippet, but that's irrelevant) and then goes on to say "...the ‘async’ attribute is set to ‘true’. Very nice! The main benefit of this is it tells the browser that subsequent scripts can be executed immediately – they don’t have to wait for ga.js."
@user265330 - So are you saying that programmatically creating a SCRIPT tag and setting the ASYNC attribute is superior to just placing the SCRIPT tag with the ASYNC attribute in the markup. The only reason to do it with JavaScript (read: programmatically) is because some browsers don't support the attribute caniuse.com/script-async
2

There was a great article from Jake Archibald on html5rocks which addresses this topic.

2 Comments

@millimoose: The article shows the differences and the consequences between the different ways to load a script. So yes it provides information related to user265330's question.
@cr0 It's generally preferred that you actually demonstrate the applicability of what you link to by excerpting the most relevant parts of it in your answer. (See the meta question.) Basically your answer should stand on its own (which it does not), and anything you link to should provide additional information. Otherwise you're likely to be upstaged by someone willing to put in more effort.
0

According to https://www.html5rocks.com/en/tutorials/speed/script-loading/ if a <script> element is added dynamically it may not be executed until DOMContentLoaded is fired. That is, some user agents (e.g. MSIE 10) will wait until DOM is ready before running dynamically added <script> elements.

I guess Google wants to get their analytics code running faster on those user agents and as such they need to add async flag to tell the browser (e.g. MSIE 10) that it's okay to start executing the script as soon as possible. HTML5 compatible browsers would execute as if the async true even if it was not defined so the async=true has been added only to improve performance with non-HTML5 browsers.

Comments

0

setting async attribute to true makes sure that the script is loaded along with the rendering of html in parallel.This is essential because if script is placed at end of body and in html we are using something that depends on javascript code,so it won't be loaded and creates issue defer can be used but defer just pauses execution of script and renders html

Comments

0

This image explains normal script tag, async and defers credit goes to https://stackoverflow.com/users/1948260/prasanth-bendra

Async scripts are executed as soon as the script is loaded, so it doesn't guarantee the order of execution (a script you included at the end may execute before the first script file )

Defer scripts guarantees the order of execution in which they appear in the page.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.