Don’t Forget the CDN
If you’re not already using Content Delivery Networks (CDNs), you should be. They’re a convenient resource that reduce the load on your web site and can improve your users’ browser experience. While working on a side project the other day, I realized I had deployed the site to production without updating some of my resource references to use a CDN. I was instead serving a number of them from the local machine, and there’s no need to do that. CDNs provide common resources (e.g., jQuery) free and quickly.
As I was fixing up my references, I decided to do more research on CDNs, and I learned some interesting points that I wanted to share. First though, let me cover the basics.
A CDN usually hosts a common file used by many applications. In the web world, scripts like jQuery are a great example of this. There’s no need for an application to pull this script from the local web server. Instead, they can point at Microsoft’s CDN and the browser will download the script from there. The Microsoft CDN hosts a number of resources beyond the base jQuery script. You can pick up jQuery UI, jQuery validation, jQuery Mobile and many others.
Here’s an example comparing a local versus a CDN script reference (please read the final point in this post about the “http” gotcha):
One obvious advantages here is that I’m not using network bandwidth for my site to send down the script. It’s also likely that the CDN is able to serve up the script faster. After doing some research though, I learned a few less obvious advantages, downsides and tips that I thought were worth sharing.
Less Obvious CDN Advantages
Imagine you’re visiting a number of different web sites and they all use the same version of jQuery, but they all host the jQuery script locally. Each time your browser requests a page from one of the sites, it downloads a copy of jQuery. If instead each of these sites pointed to the same CDN for the jQuery script, the browser would only download it once for the first site visited. When you visited the second site, the browser would see the need to download jQuery from the CDN, but we’d get a browser cache-hit for the script and nothing would be downloaded again.
Below is some HTTP traffic captured with Fiddler for requests made to two different web sites. Both sites have a reference to the jQuery script stored on Microsoft’s CDN. Notice that the first request for this script (request #10) resulted in a download of the script and an HTTP 200 response. The second request for the script (request #70) was to a different web site but didn’t require re-downloading the script. The browser made a request for it and the server (the CDN) responded with an HTTP 304 indicating the script contents have not been modified.
This is the cross-site caching effect. As more web sites reference a CDN for common resources, the chance of the client’s browser getting a cache hit when requesting such scripts goes up.
Increased browser request parallelism
Internet Explorer has settings which restrict the number of outstanding requests to a single web server and I’m sure the other browsers have similar restrictions. This Microsoft KB article talks about how to tweak this setting for IE.
Having resources pulled from a CDN means the browser is making requests to a different server than the one serving up the original web page so these requests don’t count against this “max connections per server” browser setting.
Potential Downsides to CDNs
I knew there had to be a few downsides to using CDNs. Here are a couple of them that I found interesting.
- What if the browser can’t reach the CDN? Like any other server, it’s possible that it could go down although I’d argue that it’s more likely your web server will go down than one of the major CDN’s.
- There might be some additional engineering cost to tweak your resource references on deployment to convert from locally referencing files to referencing the CDN. You could avoid this by also targeting a CDN when doing development, but that will likely be slower than having the script loaded from your local machine.
- The version of the resource you’re referencing is dropped from the CDN. This is always possible although I’m betting a good CDN would keep a long history of past versions of files. Still, you probably want to pay some attention to this so that you’re not caught off guard.
- When working with an Intranet based site, hitting a CDN might be slower than the local machine since it’s likely to be physically closer to the machine making the web request.
The HTTP/S Reference Gotcha
This issue was completely new to me. In most of the examples I’ve seen where folks show updating their resource references to CDNs (including the one at the beginning of this post), they precede the reference with “http”.
There’s a problem with this. If the resource is referenced in a page that’s downloaded securely via “https”, the browser will generate a warning and will not download the resource from the CDN because it’s not specified using “https” as well.
Here’s what happens when such a page is requested in Chrome:
Notice the warning at the top of the page and the recommended action. If the user decides to not load the content, your site could break if it depends on the resource that doesn’t get loaded.
A quick fix might be to always download CDN resources via “https”, but that’s overkill as you might have other pages in your site that use the same resource yet those pages are meant to be requested with a standard “http” connection. In such cases, we wouldn’t want to incur the browser overhead of making an “https” connection to the CDN when it’s not needed.
Fortunately, there’s a simple trick to have the CDN resource downloaded via “http” or “https” depending on how the referencing page was requested. Just trim off the leading “http:” or “https:”.
When processing this script reference, the browser will automatically prepend it with either “http” or “https” depending on the method used to request the referencing page.
Hope this helps.