Using CDN Hosted jQuery with a Local Fall-back Copy - Jon Galloway

Using CDN Hosted jQuery with a Local Fall-back Copy

Update: See Scott Hanselman's post for more info: CDNs fail, but your scripts don't have to - fallback from CDN to local jQuery

There are a lot of good reasons to stop hosting your own local copies of common Javascript includes like jQuery and ASP.NET AJAX. Dave Ward summed up the top three reasons:

Decreased Latency

A CDN — short for Content Delivery Network — distributes your static content across servers in various, diverse physical locations. When a user’s browser resolves the URL for these files, their download will automatically target the closest available server in the network…

Increased parallelism

To avoid needlessly overloading servers, browsers limit the number of connections that can be made simultaneously. Depending on which browser, this limit may be as low as two connections per hostname. Using the Google AJAX Libraries CDN eliminates one request to your site, allowing more of your local content to downloaded in parallel.

Better caching

Potentially the greatest (yet least mentioned) benefit of using the Google AJAX Libraries CDN is that your users may not need to download jQuery at all. No matter how aggressive your caching, if you’re hosting jQuery locally then your users must download it at least once. […] When a browser sees multiple subsequent requests for the same Google hosted version of jQuery, it understands that these requests are for the same file. Not only will Google’s servers return a 304 “Not Modified” response if the file is requested again, but also instructs the browser to cache the file for up to one year. This means that even if someone visits hundreds of sites using the same Google hosted version of jQuery, they will only have to download it once.

Dave refers to the Google AJAX CDN because it was the only game in town at the time of his post, but since then Microsoft has begun hosting not only jQuery, but also the ASP.NET AJAX libraries.

When you consider that this is offered as a free service, why wouldn’t you be using it?

What about outages?

There’s one potential downside to outsourcing anything: potential outages. You might be tempted to brush that aside with “Hey, it’s run on a world-class CDN...” but it can and has happened. If your depends on jQuery, any CDN outages are essentially another outage for your site.

The outage scenario is mitigated by the fact that browsers should be using cached copies rather than contacting the CDN in most cases, but that doesn’t always work out in practice.

The other outage scenario – no (or unreliable) internet connection

The most common “outage” scenario for a CDN is when the browser has no internet access at all. There are two common cases developers run into this:

  • Developing offline – Requiring a constant internet connection to develop your app can be really frustrating. It means you can’t develop when you’re mobile or travelling, and even when you’ve got a connection it can slow down your development feedback cycle.
  • Demonstration and sample code – If you’re presenting an app or sharing demo code, depending on CDN access is an invitation to the demo gods to rain doom on your head.

The simple solution: Use a fallback when the CDN’s unreachable

Here’s a general pattern for AJAX includes with a fallback: include the CDN reference, test for a key object, and if it’s undefined you can write out a reference to a copy that you’re hosting. Here’s how that looks when using the Microsoft hosted jQuery libraries with an ASP.NET MVC application:

<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery/jquery-1.3.2.min.js"></script>
<script type="text/javascript">
if (typeof jQuery == 'undefined')
{
    document.write(unescape("%3Cscript src='/Scripts/jquery-1.3.2.min.js' type='text/javascript'%3E%3C/script%3E"));
}
</script>

And here’s how I’d set that up with ASP.NET AJAX library references in an ASP.NET MVC app:

<script src="http://ajax.microsoft.com/ajax/3.5/MicrosoftAjax.js" type="text/javascript"></script>
<script src="http://ajax.microsoft.com/ajax/mvc/1.0/MicrosoftMvcAjax.js" type="text/javascript"></script>    
<script type="text/javascript"> 
if (typeof Sys == 'undefined') 
{
    document.write(unescape("%3Cscript src='/Scripts/MicrosoftAjax.js' type='text/javascript'%3E%3C/script%3E"));
    document.write(unescape("%3Cscript src='/Scripts/MicrosoftMvcAjax.js' type='text/javascript'%3E%3C/script%3E"));
} 
</script> 

Correctly handling virtual roots on ASP.NET

Rick Anderson reminded me that the above doesn't work well in a virtual root - you need to remove the leading / in the script references. A better approach in ASP.NET / Razor is to use Url.Content, which handles that automatically:

<script type="text/javascript">
if (typeof jQuery == 'undefined') {
  var e = document.createElement('script'); 
  e.src = '@Url.Content("~/Scripts/jquery-1.7.1.js")';
  e.type='text/javascript'; 
  document.getElementsByTagName("head")[0].appendChild(e); 
 
}
</script> 

But will it blend?

It carries the “works on my machine” guarantee. One easy way to test is to mangle the CDN references – change “ajax.microsoft.com” to “kissypoo.microsoft.com”. You’ll get a Javascript error due to the bad reference, but the fall-back reference will be loaded. You can verify that by debugging the code.

This also carries the “Lots of Upvotes On StackOverflow” guarantee, and you can see from the comments on Dave’s post that he’s looked into it, too.

Published Thursday, January 21, 2010 1:31 AM by Jon Galloway

Comments

# re: Using CDN Hosted jQuery with a Local Fall-back Copy

Doesn't the Ajax script loader handle this for you so you don't have to repeat yourself?

Thursday, January 21, 2010 5:04 AM by haacked

# re: Using CDN Hosted jQuery with a Local Fall-back Copy

@haacked - The AJAX Script Loader handles loading scripts, but I don't think it handles a local fallback, does it? www.asp.net/.../Ajax%20Script%20Loader.ashx

Thursday, January 21, 2010 5:26 AM by Jon Galloway

# re: Using CDN Hosted jQuery with a Local Fall-back Copy

Excellent idea. However, my experience with such outage was that the page just wouldn't load waiting for script to finish loading. In this case your technique wouldn't help - any ideas how to deal with that side of the issue?

Friday, January 22, 2010 5:10 AM by Vitaly

# re: Using CDN Hosted jQuery with a Local Fall-back Copy

@Vitaly: That will be the case if the CDN is down in a way that results in a long timeout.

Any other "quick" error condition (like being in a country that the CDN doesn't serve) will immediately fall through to the local copy.

Friday, January 22, 2010 8:36 AM by Dave Ward

# re: Using CDN Hosted jQuery with a Local Fall-back Copy

Slightly related, but any news on when jquery-1.4 will be up on the Microsoft CDN?

Friday, January 22, 2010 3:19 PM by Scott Wade

# re: Using CDN Hosted jQuery with a Local Fall-back Copy

definitely very cool.

will be using this in the future fooo showwaa :-)

Thursday, January 28, 2010 1:04 AM by Doug Rathbone

# re: Using CDN Hosted jQuery with a Local Fall-back Copy

Hey, this works great.

Thanks, moreover, unlike other scripts, this doesn't fails to validate.

I have a question, can I put this code into separate js file?

Regards

Krunal

Thursday, September 9, 2010 9:57 AM by Xcellence IT

# re: Using CDN Hosted jQuery with a Local Fall-back Copy

I like what you guys are up too. Such clever work

and coverage! Keep up the excellent works guys I've added you guys to my personal blogroll.

Wednesday, February 6, 2013 6:54 AM by Branham

# re: Using CDN Hosted jQuery with a Local Fall-back Copy

Why visitors still make use of to read news papers when in this technological world the whole thing is

presented on net?

Saturday, March 16, 2013 3:14 AM by Bradbury