Cross-Browser Asynchronous JavaScript Script Loading

Asynchronous

JavaScript LogoWhile it is perfectly normal to have one or more JavaScript tags in your markup as prerequisites to your code, there may be situations in which you want to avoid this

When I build a piece of functionality that is contained in one JavaScript file, I try to avoid asking the back-end developer to include additional scripts in the markup. So, my philosophy is: my script provides a certain “chunk” of functionality. Whatever external resources my script depends on are my script’s problem and will be handled accordingly. As often as possible, I’d like the consumer to simply choose to use or not use my script. This decision should involve simply adding or removing my script from the markup. The remaining abstraction is my responsibility.

This may seem a bit altruistic, but so far I’ve never had to lower my standards on the issue. The key to keeping this philosophy is, of course, the ability to reliably load other scripts asynchronously. I say “reliably” because it’s not enough to simply inject the script into the head of the document. You need to know when that script has successfully loaded before you take further actions that depend on the script.

The good news is: modern browsers provide the “onload” event, allowing you to set up your handler without too much effort. But the bad new is: Microsoft’s Internet Explorer 8 and below do not implement that event. So, there is some work to do. It’s not too bad; it just means we need to fork our code a bit.

Oh, and by the way; you might be wondering why I didn’t simply use the jQuery.getScript() method. jQuery is awesome and we all love it more than coconut ice cream. But I strongly believe that it’s important to know how to do these things with native JavaScript. One day a client will tell you that for whatever reason, you can’t use jQuery. When that day comes, you’ll be ready.

So let’s have at it!

Example # 1

Now here in Example # 1, we’ve created a function that takes a URL and a callback as arguments. The URL is required, the callback is optional. As you can see, this is pretty straightforward stuff:

  1. Create a script DOM element
  2. Assign an anonymous function to the “onload” event
  3. Set the script’s source
  4. Inject the script into the DOM

No worries.

Example # 2

In Example # 2 we have rolled up our pant legs and stepped into the cold wet mud that is Internet Explorer 8 (and below). So here we will need to assign that same anonymous function to the script element’s “onreadystatechange” property. And this property will change as the “ready state” of the script element updates. When that ready state is “loaded”, then we can be confident that the external script has successfully loaded and executed. It’s a bit more work, but then again, Internet Explorer wouldn’t be such a charming little browser if it adhered to the same kind of common-sense standards as every other modern browser on the planet… but I digress.

Example # 3

Well… Example # 3 certainly contains a bit more code, huh? In fairness, it’s heavily commented. But outside of that, what has happened is that as promised, we’ve forked the code so that we can support good ol’ IE, as well as all the other browsers that are made by sane people. I chose to check for the existence of document.attachEvent as a way of sniffing the browser. Some may disagree, but for me, it has always worked just fine.

If you follow the link to the full working example below, be sure to open your JavaScript console. When you do, you’ll see that the message from the actual external script always fires before the callback. Always. This is what we needed: the ability to load the script, and reliably know when it has loaded so that we can safely assume whatever resources it provides are available to us. So go ahead and try it in Internet Explorer 8 or Internet Explorer 7; it works just fine.

The full working example can be found here: http://examples.kevinchisholm.com/javascript/script-loading/

Summary

In this article, we learned how to implement a reliable solution for cross-browser asynchronous JavaScript loading. We discussed the need to fork our code in order to support Internet Explorer 8 (and below), and the “onreadystatechange” event that it implements.

Helpful Links for JavaScript loading

http://css-tricks.com/thinking-async/

http://friendlybit.com/js/lazy-loading-asyncronous-javascript/

Book Review: Async JavaScript, by Trevor Burnham

Asynchronous

Async JavaScript, by Trevor Burnham - CoverLearn to master the tricky nature of asynchronous JavaScript with “Async JavaScript – Recipes for Event-Driven Code“. This short yet thorough book explains many concepts which not only demystify the subject, but also arm you with tools to architect smarter solutions.

There are books that explain how JavaScript works, and then there are books that transform your perception of the language. Trevor Burnham’s “Async JavaScript” is the latter.

Maybe you had your first JavaScript “aha!” moment when you used the document.addEventListener() method to create your first click handler. Or maybe it was the wonderment of running some free-form code in the console and watching the web page change. Regardless of which context kicked-off your fascination with JavaScript, the intimate relationship between the DOM and this dynamic language is one of the things that make it so special. That “real time” aspect of JavaScript development is addictive.

But once you ascend to real-world problem solving, the asynchronous nature of JavaScript can be a buzzkill. The only way to slay this dragon and return to the zombie-like euphoria of JavaScript development is to dive into this topic, master it, and then gently place your sword back into its sheath.

It can be done.

Async JavaScript covers every angle and does it quite well. Starting with the JavaScript event model, it introduces you to the tricky nature of how the language handles events. Mr. Burnham then provides a surprisingly refreshing explanation on the setTimeout() and setInterval() methods, rescuing them from the “anti-pattern” monikers they have unfairly accumulated over time because of their improper use.

Before you can count to 100 milliseconds, you are whisked away, into a whirlwind of concepts that help to demystify JavaScript’s asynchronous nature. In a clear and concise manner, concepts such as the Pub/Sub model, custom events, Promises/Deferreds and Web Workers are detailed, as well as numerous libraries that help to implement these patterns.

I can’t recommend this book enough. As you start to write intermediate-level JavaScript, you find pebbles in your shoe. Quite often, these pebbles arise from tricky asynchronous JavaScript problems. Async JavaScript by Trevor Burnham is an invaluable resource. It not only explains how JavaScript processes events, but also provides numerous perspectives that help to understand and master its asynchronous nature.

Note: This book is no longer available in paperback, just the Kindle edition. It has been revised and updated, and is now a “PragProg” book.

  • Title: Async JavaScript
  • Author: Trevor Burnham
  • Publisher: Leanpub
  • Publication Date: March 20, 2012
  • Print Length: 88 pages
  • Language: English
  • ASIN: B007N81FE2
  • ISBN: 1475247362