A reader recently wrote in and (essentially) asked me:
Is there any reason to use the
async
attribute when thescript
is already at the bottom of the page?
I’m not a master at this stuff, but this is how I understand it…
What he was talking about was this:
<script async src="/js/script.js"></script>
</body>
We’ve covered this before a bit. It’s extra-interesting to re-visit now though, because the async
attribute is now really the only recommended way to be doing async scripts.
So, is there any reason to use the async
attribute when the script
is already at the bottom of the page?
Short Answer
No.
Longer Answer
What you are trying to prevent with the async
attribute is parser blocking. If you use the async
attribute, you are saying: I don’t want the browser to stop what it’s doing while it’s downloading this script. I know that this script doesn’t really depend on anything being ready in the DOM when it runs and it also doesn’t need to be run in any particular order.
If you load the script at the bottom of the page, the parser is effectively done already, so blocking it isn’t a big deal. You’re essentially already deferring the script, which is kinda like a more hardcore async. See comparison.
It might even be a little dangerous.
If you were just operating under the assumption that async = good, you might do something like:
<script async src="/js/libs.js"></script>
<script async src="/js/page.js"></script>
</body>
That could be bad news, because chances are “libs.js” has dependencies for “page.js”, but now there is no guarantee the order in which they run (bad).
It’s mostly third-party thing.
Third-party scripts are the big use-case for async scripts. They (the third-parties) can’t control where you put that script on your page, so they are typically designed to work no matter when/where they load anyway. You also can’t control third-parties (that’s what a third-party is, Wayne) so making darn sure they don’t slow your site down is ideal.
Is there any other use-cases?
I guess if you really wanted to get the download started on one of your own scripts right away, and it didn’t matter when it ran, you could put it in the <head>
and async it.
I might be kinda wrong.
I tend to screw up these JavaScript advice posts, so if I did, let’s talk about it in the comments and I’ll make sure the content of this post reflects the best information.
There is still a usecase to use async, although it was put at the bottom. Any script added sync inside the document blocks the domcontentloaded (ready) event, which is often used to initialize UI widgets/components.
But you are absolutley right. The most important use case for async nowadays would be third party code, which must be loaded async or better using friendly iframe technique. Unfortunaltey this is often impossible, because of bad written scripts.
I like the short answer, it’s cleaner.
+10
According to a comment by the author in the article linked @ igvita.com there is still a benefit:
Thanks for this post, I wouldn’t have learned these tidbits about async otherwise!
See: https://www.igvita.com/2014/05/20/script-injected-async-scripts-considered-harmful/#comment-1398899164
Does that mean the preloader can’t find scripts that don’t have the async attribute? That seems weird. Just wondering here, I’ll have to dig into that conversation to find out more.
@ Chris Coyier: Both are discoverable by the preload scanner. But if you have (say) two scripts that aren’t interdependent, marking each with the async flag lets the browser run them in either order, and so if (say) the first one is being being slow to download, the browser is free to go ahead and run the second one before the first one finishes downloading and gets run. If you leave off the async, the second still has to wait for the first. So it still has a useful purpose, even when the scripts are right at the end of the HTML.
@ChrisCoyier @Chris The quote is about using the async attribute vs using script injection. It doesn’t address whether or not to use the async attribute on a script tag.
My understanding of the async attribute is well summarized by @T.J.Crowder. The async attribute is beneficial if you know what you’re doing, but is not a good default for bottom-loaded script tags, as Chris concluded in the article.
While I agree that you shouldn’t use it because it doesn’t guarantee the order of execution… By using the async attribute, it actually executes the script twice as normal script tag. Injecting via the script tag into the dom takes 0.1sec longer on average but I still think that’s the best solution.
Twice as fast**. Chris above comment is also correct.
Is there any reason to use the
async
attribute when thescript
is already at the bottom of the page?i say: No, bu sometime Yes!
when bottom
script
is independent from each other, we can useasync
so the latency of loading first script does not affect second one.Further question. If you were loading, say, 10 scripts at the bottom of your page and there were no dependencies, would loading them all async help them to load faster, all in parallel, rather than maybe 6 requests then a further 4?
I have a die-hard backend dev friend who swears that putting scripts at the bottom of the page is bad practice and gets really annoyed when he is searching through pages trying to find the scripts and then finds them below. Is it really preferable to place them before the end of the body or is it mostly a convenience thing?
Does he have any reasoning as to why that would be bad practice – I mean, apart from that is just “annoys” him that it takes him a little longer to find them …?
Should anyone want to dive a little deeper. This is my go to article for JS loading, I’ve found it very informative in the past.
http://www.html5rocks.com/en/tutorials/speed/script-loading/
josh:
Its not for convenience, its for performance. Adding the scripts before the body will increase the rendering time. With some exception, some analytic script prefer developer to put the script on the head, this is so that they can track it as soon as the page is being called.
What about just using async with 1 concatenated script instead of breaking them all apart, worrying about execution order and potentially burning http requests? Running
cat *.js > app.min.js
on the command line over your JS file will concatenate everything.Concatenation is another issue I think. It’s important. From the perspective of this article, it should be assumed you’ve already done as much intelligent concatenation as possible. Just because a page loads two scripts doesn’t mean they are dropping the ball on concatenation. It might make perfect sense to have a
global.js
that loads on all pages (and thus leverages caching) andsubpage.js
which loads only on some pages, but depends on stuff from global.@ Chris Coyier: Bang on. Or you’ve made the business decision to download standard things from a free CDN and your own stuff locally (and dealt with handling what happens if those are in a chaotic order).
None of this stuff is dogma. It’s pragmatic choices, intelligently made.
Or at least, you know, that’s what we’re shooting for anyway… ;-)
What about asynchronously loading scripts like this?
Hmm, I wanted to insert HTML code…
<script src=”/js/AsyncLoader.js”></script>
<script>
AsyncLoader.Ready(function () {
AsyncLoader.Load([“jQuery”, “extensions”], function () {
// Application code here.
});
});
</script>
http://www.dustindiaz.com/scriptjs
async loading with dependency management KAPOW.
A dependency attribute would be better but as it doesn’t exist this is v useful.
Thanks for your clarification. Recently I have been facing the async issue on my project. I prefer loading the script at the footer. But is there any disadvantage of placing the script at the bottom of page ? Even one ?