2010-01-23

HTML5 will lower the use of CDNs for delivering JavaScript

As Firefox 3.6 was released today, people have begun to use the async attribute for the script tag from HTML5. For those of you unaware of the new attribute, it tells the browser to execute the JavaScript that a script tag points to through its src attribute in an asynchronous manner. Now from my reading of the spec that should be asynchronously, but one at a time based on the order of the script tags are found in the doc. But if you play with Firefox 3.6 it becomes apparent that Mozilla disagrees with my interpretation as Firefox will begin executing the next async JavaScript file without waiting for the previous one to finish.

And this immediate execution is where things begin to make things interesting for using a CDN for JavaScript code. I don't know about some of you, but I use the Google AJAX Libraries
to get my copy of jQuery through their URL interface. This is great for me as it means the traffic is served by someone (i.e. free for me), Google's CDNs are fast, and there is a decent chance that others have used the CDN as well which lets the browser uses a cached copy of jQuery instead of fetching it again just for my web app. This means you don't concatenate jQuery in with your JavaScript code to get a single JavaScript file to serve, but my thinking (until now) has been that the perk of the browser already having a cached copy of jQuery was enough to not care about the potential separate HTTP request.

But you can't reliably use the async attribute with library code that subsequent JavaScript code depends on. In my case I use jQuery to execute JavaScript code once the page is loaded and rendered. When I put the async attribute on both the CDN-served jQuery code and on my own code, I was able on my local machine to occasionally trigger a race condition where my JavaScript code was executed before jQuery, triggering an error as $ was not defined yet. It was tough to trigger, but it definitely happened.

This means either you execute the CDN-served library code synchronously or you concatenate it with your code and serve that entire file asynchronously. The decision then becomes what gives you more benefit: possible faster downloading from a CDN plus cache hits but blocking JavaScript execution, or having to download from your servers but having fully asynchronous execution.

Now some of you might view this as a somewhat thin argument that CDNs serving JavaScript will get marginalized, and that's fair. But what I really think will impact it is offline web applications and the app cache. For a web application to work offline you define a cache manifest file which lists what URLs to cache, which URLs to hit a specific file if not online, and which ones should always go to the network no matter what. But at issue here is the fact that all listed URLs must follow the same-origin policy. This means that for you to serve up some JavaScript library while offline you need to have it hosted on your server to be able to list it in your cache manifest to get the benefits of an offline web app.

As people begin to look at offline web apps more and more I think it will be interesting to see how this impacts people's use of CDNs for stuff like JavaScript.