O'Reilly

HTML5’s async Script Attribute

By on  

HTML5 Async Script

One of the big reasons I'me excited about HMTL5 is that features are being implemented that have been long overdue.  We've been using placeholders forever but we've needed to use JavaScript to do it.  We've been making entire blocks clickable like links but we've needed to use JavaScript to do it.  WebKit recently implemented HTML5's async attribute for SCRIPT tags.  We've been accomplishing this task with a variety of JavaScript hacks but this new attribute will allow us to prevent blocking in an easy way.

async - The HTML

As I mentioned above, it's as easy as adding an attribute:

<script async src="siteScript.js" onload="myInit()"></script>

The truth is that if you write your JavaScript effectively, you'll use the async attribute to 90% of your SCRIPT elements.

defer - The HTML

Safari has also added a defer attribute:

<script defer src="siteScript.js" onload="myInit()"></script>

Very similar to the async assignment.

async & defer - What's the Difference

This WebKit blog post explains the difference between defer and async best:

Both async and defer scripts begin to download immediately without pausing the parser and both support an optional onload handler to address the common need to perform initialization which depends on the script. The difference between async and defer centers around when the script is executed. Each async script executes at the first opportunity after it is finished downloading and before the window’s load event. This means it’s possible (and likely) that async scripts are not executed in the order in which they occur in the page. The defer scripts, on the other hand, are guaranteed to be executed in the order they occur in the page. That execution starts after parsing is completely finished, but before the document’s DOMContentLoaded event.

Who Supports async and defer?

Also from the Safari blog:

In addition to upcoming versions of WebKit-based browsers, Firefox has long supported the defer and onload attributes and support for async was added in version 3.6. Internet Explorer has also long supported the defer attribute. While async is not yet supported, support for the onload attribute was added in version 9.

async FTW!

Seeing that WebKit had implemented async put a huge smile on my face.  Blocking is a huge bottleneck for every website and the ability to easily direct a script to load asynchronously should speed up the web!

Track.js Error Reporting

Upcoming Events

Recent Features

  • Introducing MooTools Templated

    One major problem with creating UI components with the MooTools JavaScript framework is that there isn't a great way of allowing customization of template and ease of node creation. As of today, there are two ways of creating: new Element Madness The first way to create UI-driven...

  • Responsive and Infinitely Scalable JS Animations

    Back in late 2012 it was not easy to find open source projects using requestAnimationFrame() – this is the hook that allows Javascript code to synchronize with a web browser's native paint loop. Animations using this method can run at 60 fps and deliver fantastic...

Incredible Demos

  • Google Extension Effect with CSS or jQuery or MooTools JavaScript

    Both of the two great browser vendors, Google and Mozilla, have Extensions pages that utilize simple but classy animation effects to enhance the page. One of the extensions used by Google is a basic margin-top animation to switch between two panes: a graphic pane...

  • Jack Rugile&#8217;s Favorite CodePen Demos

    CodePen is an amazing source of inspiration for code and design. I am blown away every day by the demos users create. As you'll see below, I have an affinity toward things that move. It was difficult to narrow down my favorites, but here they are!...

Discussion

  1. Okay… so what is the benefit of the async tag vs defer. It seems that in all use cases defer is just as efficient and more useful as it will prevent nasty dependency problems?

    Please explain why async is ftw better than defer…

  2. Nice! Way better than putting the scripts at the bottom of the <body>

  3. @benjamin : you could use async for scripts that does not depend on other scripts to run. I’m thinking about scripts such as Google Analytics, for instance.

    @David Walsh: is it possible to mix async and defer? I’m explaining my thoughts: If I’ve two scripts A and B that depends both on a library (like mootools), but haven’t any dependencies together, could I do:

    1. defer mootools
    2. async A
    3. async B

    so mootools will be loaded first, and then A and B in any order?

    So, I’m clarifying my question: what’s the priority between defer and async:
    1. defer over async, like above
    2. async over defer / none, means A and B could be loaded before mootools

    Thanks for your blog David, it’s delightful

    • @Alexander Mercier you said that it’s possible to mix ‘async’ and ‘defer’. So you’re saying that I can use ‘defer’ for a library (like jQuery) and ‘async’ for any other like Google Analytics. What about top header modernizr.js? Can I use ‘async’ for it?

  4. Champ

    Walshe… I have been checking your stuff out, and it looks good! The JS looks big and bulky and I am wondering if its going to hurt the first time I implement it. Any advice?

  5. Thank you for the great article Walsh!

    @Alexandre: I was also wondering something similar and I read a bit of interesting text in this article:

    “The defer attribute may be specified even if the async attribute is specified, to cause legacy Web browsers that only support defer (and not async) to fall back to the defer behavior instead of the synchronous blocking behavior that is the default.”

    To better explain my situation: I’m not only interested in making sure my scripts load in the correct order (as you are) but I’m also very interested in each being non-blocking across as many browsers possible (including legacy browsers).

    While this may not directly answer your question I believe it may be helpful to your case (and mine). It sounds like async will override defer if it (async) is supported, so it would be safest to give your first script (mootools) a defer attribute, and then give your other scripts (A and B) both async and defer attributes. I could be totally misunderstanding the use of these here, so someone please correct me if I’m wrong.

    @Walsh: Do you have any insight you can add this particular topic?

  6. how long does it take for updates to webkit like this to make it out into the wild of production chrome/safari?

    it seems like this should have been a standard across all modern browsers long ago (i know, i know, if you had a nickel…), if only for the single use case of allowing publishers to load ads after content. think of all the billions of seconds wasted…

  7. rajkamal

    @Alexandre Mercier :
    async scripts execute at the first opportunity after download and before window onload event. So there is a possibility of script A or script B getting getting executed even before executing MooTools. Because as MooTools is given Defer attribute , it will get the first opportunity of executing only just before the DomContentLoaded event.So there may be some dependency errors.correct?

    @ David Walsh,

    Post comment button is not working ;-(
    i used this to post my comment

    var form = document.forms[1];
    var request = new Request({
    url: form.get('action'),
    method: form.get('method'),
    link: 'ignore',
     onRequest: function() {
    dotter.start();
     indicator.fade(1);
     }
    }).send(form.toQueryString());
    
  8. Hey, David; My recent tests show that the only browsers to support script async are FireFox 3.6+ and Chrome. I’m running tests for defer, but Safari definitely doesn’t support it; so perhaps it doesn’t have the latest version of Webkit support.

    I wrote a simple test which I ran through BrowserCam. The link is here:

    http://test.marketruler.com/js/async.php

    The embedded async_js.php script does a 2 second delay, then returns its results which set a global value to true.

    • That test is insanely useful! (and will remain so over time as unsupported browsers release new versions)

      Thanks!!!

    • Awesome Kent! Thanks for doing some legwork!

    • Well, it’s my business, but no problem. I’ll report back after the defer tests. I wrote an article on our wiki here:

      http://wiki.marketruler.com/How_does_JavaScript_run_on_a_web_page%3F

      which kind of covers the issue as I understand it.

    • Final point: Script “defer” attribute is supported by Chrome, FireFox 3.6+, and Internet Explorer 5+ on Windows. Worthwhile if you want to speed up your pages.

  9. David

    Actually, the webkit’s blog isn’t relevant anymore about the async attribute. If a script has async attribute it can be executed after the DOMContentLoaded event was fired:

    http://dev.w3.org/html5/spec/the-end.html

    But since the post was written in 2010 the spec was probably different then.

  10. Chung Xa

    As you said, the only difference between async and defer is when the script is executed. For me, the browser can run the script very fast, so it doesn’t matter to consider the different speed although the async is a bit faster but not significant..

    After all, I still prefer the defer attribute because it guarantees everything will work fine without worries :P

  11. Is it possible for ASYNC scripts to be executed before DEFER scripts? If so, how does one make sure a script like jquery.js is ready for other scripts that will depend on it? Must jQuery be a blocking script (i.e., not using ASYNC or DEFER)?

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Recently on David Walsh Blog

  • Generating Alternative Stylesheets for Browsers Without @media

    If your CSS code is built with a mobile-first approach, it probably contains all the rules that make up the "desktop" view inside @media statements. That's great, but browsers that don't support media queries (IE 8 and below) will simply ignore them, ending up getting the...

  • Serve a Directory with PHP

    Many developers have a giggle at PHP, even looking down at the language, but let's be honest:  most of our blogs are powered by it (WordPress) and it's a great language to dabble around with.  I cut my teeth on PHP, though I prefer to avoid PHP these days. But...

  • Tips you can Use to Build an Excellent eCommerce Experience

    There are many reasons to build a good eCommerce experience if you are planning to build an eCommerce website. Visitors can place items in their cart and leave your site without making a purchase. In fact, three out of every four of them will do so....

  • OSCON: Live Stream

    O'Reilly's OSCON is upon us and I'm super excited to share with you a live stream of OSCON keynotes, courtesy of O'Reilly! Check back here every morning this week to get a sneak peek at the best conference in the open source community! Thank you...

  • OâReilly Velocity Conference â New York

    My favorite front-end conference has always been O'Reilly's Velocity Conference because the conference series has focused on one of the most undervalued parts of client side coding:  speed.  So often we're so excited that our JavaScript works that we forget that speed, efficiency, and performance are just as important. The next Velocity...