javascript – Multiple files on CDN vs. one file locally-ThrowExceptions

Exception or error:

My website uses about 10 third party javascript libraries like jQuery, jQuery UI, prefixfree, a few jQuery plugins and also my own javascript code. Currently I pull the external libraries from CDNs like Google CDN and cloudflare. I was wondering what is a better approach:

  1. Pulling the external libraries from CDNs (like I do today).
  2. Combining all the files to a single js and a single css file and storing them locally.

Any opinions are welcome as long as they are explained.
Thanks 🙂

How to solve:

The value of a CDN lies in the likelihood of the user having already visited another site calling that same file from that CDN, and becomes increasingly valuable depending on the size of the file. The likelihood of this being the case increases with the ubiquity of the file being requested and the popularity of the CDN.

With this in mind, pulling a relatively large and popular file from a popular CDN makes absolute sense. jQuery, and, to a lesser degree, jQuery UI, fit this bill.

Meanwhile, concatenating files makes sense for smaller files which are not likely to change much — your commonly used plugins will fit this bill, but your core application-specific code probably doesn’t: it might change from week to week, and if you’re concatenating it with all your other files, you’d have to force the user to download everything all over again.

The HTML5 boilerplate does a pretty good job of providing a generic solution for this:

  1. Modernizr is loaded from local in the head: it’s very small and
    differs quite a lot from instance to instance, so it doesn’t make
    sense to source it from a CDN and it won’t hurt the user too much to
    load it from your server. It’s put in the head because CSS may be
    making use of it, so you want it’s effects to be known before the
    body renders. Everything else goes at the bottom, to stop your
    heavier scripts blocking rendering while they load and execute.
  2. jQuery from the CDN, since almost everyone uses it and it’s quite heavy. The user will probably already have this cached before they
    visit your site, in which case they’ll load it from cache instantly.
  3. All your smaller 3rd party dependencies and code snippets that aren’t likely to change much get concatenating into a plugins.js
    file loaded from your own server. This will get cached with a
    distant expiry header the first time the user visits and loaded from
    cache on subsequent visits.
  4. Your core code goes in main.js, with a closer expiry header to account for the fact that your application logic may change from
    week to week or month to month. This way when you’ve fixe a bug or
    introduced new functionality when the user visits a fortnight from
    now, this can get loaded fresh while all the content above can be
    brought in from cache.

For your other major libraries, you should look at them individually and ask yourself whether they should follow jQuery’s lead, be loaded individually from your own server, or get concatenated. An example of how you might come to those decisions:

  • Angular is incredibly popular, and very large. Get it from the CDN.
  • Twitter Bootstrap is on a similar level of popularity, but you’ve got a relatively slim selection of its components, and if the user doesn’t already have it it might not be worth getting them to download the full thing. Having said that, the way it fits into the rest of your code is pretty intrinsic, and you’re not likely to be changing it without rebuilding the whole site — so you may want to keep it hosted locally but keep it’s files separate from your main plugins.js. This way you can always update your plugins.js with Bootstrap extensions without forcing the user to download all of Bootstrap core.

But there’s no imperative — your mileage may vary.

Leave a Reply

Your email address will not be published. Required fields are marked *