Here's the rub: when you load JavaScript from a third party you should do it asynchronously. You might want to load your own scripts asynchronously too, but for this article let's focus on third parties.

There are two reasons for this:

If the third-party goes down or is slow, your page won't be held up trying to load that resource. It can speed up page loads.

At Wufoo, we just switched over to an asynchronous embed snippet. Users who build forms with Wufoo and want to embed them on their site are now recommended to use it. We did it for exactly those reasons above. It's the responsible thing to do for a web service that asks people to link to resources on that services site.

Let's explore this whole async thing.

Uhm. What?

There is a little terminology involved here that will help us understand the umbrella "asynchronous" term.

"Parser blocking" - The browser reads your HTML and when it comes to a <script> it downloads that entire resource before moving on with the parsing. This definitely slows down page loads, especially if the script is in the head or above any other visual elements. This is true in older browsers as well as modern browsers if you don't use the async attribute (more on that later). From the MDN docs: "In older browsers that don't support the async attribute, parser-inserted scripts block the parser..."

To prevent problematic parser blocking, scripts can be "script inserted" (i.e. insert another script with JavaScript) which then forces them to execute asynchronously (except in Opera or pre 4.0 Firefox).

"Resource blocking" - While a script is being downloaded, it can prevent other resources from downloading at the same time as it. IE 6 and 7 do this, only allowing one script to be downloaded at a time and nothing else. IE 8 and Safari 4 allow multiple scripts to download in parallel, but block any other resources (reference).

Ideally we fight against both of these problems and speed up page loading (both actual and perceived) speed.

The HTML5 Way

There is an async attribute for the script tag in HTML5 (spec). Example:

<script async src="https://third-party.com/resource.js"></script>

The browser support for it is Firefox 3.6+, IE 10+, Chrome 2+, Safari 5+, iOS 5+, Android 3+. No Opera support yet.

If you are going to load a script directly like that, using this attribute is probably a good idea. It prevents parser blocking. These newer browsers don't have any big problems with resource blocking, but the parser thing is a big deal. We aren't using this at Wufoo because we need way deeper browser support than that.

The Classic Async Way

Here is the basic async script loading pattern that will get you as deep of browser support as you'd ever need:

<script> var resource = document.createElement('script'); resource.src = "https://third-party.com/resource.js"; var script = document.getElementsByTagName('script')[0]; script.parentNode.insertBefore(resource, script); </script>

Here's a more efficient version with a wrapper around those variables (credit Mathias Bynens):

(function(d, t) { var g = d.createElement(t), s = d.getElementsByTagName(t)[0]; g.src = 'https://third-party.com/resource.js'; s.parentNode.insertBefore(g, s); }(document, 'script'));

Update: Note that this is async attribute. Note that this is no longer recommended! The era that made this a useful pattern is over, and you should mostly just use theattribute.

Ad Networks

BuySellAds is an advertising network that was one of the first to deliver ads asynchronously. This is their pattern:

<script type="text/javascript"> (function(){ var bsa = document.createElement('script'); bsa.type = 'text/javascript'; bsa.async = true; bsa.src = 'https://s3.buysellads.com/ac/bsa.js'; (document.getElementsByTagName('head')[0]||document.getElementsByTagName('body')[0]).appendChild(bsa); })(); </script>

Couple of things to note here:

They are setting the async attribute of the script to true before appending it. This is useful exclusively for Firefox 3.6 which is the only browser that doesn't do that by default. This can probably be omitted in most scenarios. Setting the