Performance of jQuery UI and Public CDNs

Google, Microsoft, and Yahoo all have content delivery networks (CDNs) to provide common JavaScript libraries for public use. This is a great service which helps to speed up the web by allowing many different sites to link to the same JavaScript library, increasing the chance a user will have a file in their cache. If you are currently hosting your own copy of a library like jQuery, switching to the Google CDN is usually an easy way to improve the speed of your site.

Full vs Custom jQuery UI

Google also provides jQuery UI on their CDN so it seems natural to assume that you should use that as well. And if you are using most of jQuery UI, then you probably should. However, many sites only use a few pieces of the jQuery UI library. For example, at FilterPlay we only use the slider. Fortunately the jQuery UI download page lets you select only the components you need and will then create a custom download.

Public CDNs Only Reduce Transfer Costs

While this custom version is nice, you have to host it yourself because the Google CDN only provides the full version of jQuery UI. The full file is much larger, 51 KB (minified + gzip) compared to 6 KB for just the pieces necessary for the slider. However, it’s still temping to think that it might be better to use the full jQuery UI on the Google CDN. There is a good chance that users will already have a copy of jQuery UI from Google in their cache. So your site should be much faster for most users right? No!

Transfer is a One-Time Cost

Transfer speed is only one aspect of the overall performance of scripts. Users will download static files like css and JavaScript on the first page, but if you have correctly configured caching, then they won’t have to be downloaded on subsequent requests. Its a one-time hit. In the past, browsers would serialize the download of scripts but modern browsers are good at downloading multiple scripts in parallel. Plus, there are some great libraries like LABjs which ensure scripts are downloaded in parallel and do not block subsequent resource downloads.

Evaluation Occurs on Every Page View

The transfer cost of a script might be zero because its already in the cache from a previous page or another site if using the Google CDN. However, the script has to be parsed and executed on every page view regardless of whether it was fetched from the cache. While scripts can be downloaded in parallel, JavaScript is single-threaded so execution of the scripts must be serialized. Over the long run, evaluation can have a much greater impact on your site performance than transfer time.

Full jQuery UI Example

To illustrate, we’ll look at some of the scripts loaded by a typical product page on FilterPlay:

Name Description Changes
LAB-1-2.min.js.gzip The LABjs library which loads scripts in parallel Very rarely
jquery.min.js jQuery hosted on the Google CDN Every few months
jquery-ui.min.js jQuery UI hosted on the Google CDN Every few months
libraries.min.js.gzip Other libraries used on FilterPlay Every few months
filterplay.min.js Page functionality Every week

You can use the Network tab in Google Chrome (similar tools exist for Firefox and IE as well) to view details about the transfer of each script:

I cleared the cache so all scripts would have to be downloaded. After LABjs, all the remaining scripts are downloaded in parallel. Even though they are downloaded out of order, LABjs can be configured to execute them in order to preserve intra-script dependencies. We can see the evaluation of the scripts using the Timeline tab:

This test was run with a full cache just so its clear that waiting for downloads is not what causes serialized execution. You can see that evaluation of jQuery UI is pretty substantial – about 60ms.

Custom jQuery UI Example

Now we’ll switch from using the full jQuery UI hosted on Google’s CDN to a custom version of jQuery UI with only the components necessary for the slider. We’ll combine the jQuery UI script with the rest of the code in libraries.js so we can save the overhead of downloading an extra file. The file size increases by about 20 KB but that is reduced to only 5 KB larger after gzip. However, look at the difference in evaluation:

You might have noticed that the first script began execution at a later time than in our first test. There is some variation in timing based on the prior events which can be ignored. Focus on the amount of time each of the scripts took to execute (the length of the gold bars). The libraries file took a little longer to evaluate since it now includes pieces of jQuery UI. However, it should be clear that it took far less time (net +10ms) than the full jQuery UI (60ms).

A 50ms difference may not seem like a lot, but remember you pay this cost on every page, unlike the download cost which is only paid once. More importantly, it removes 50ms from the serialized page execution which is far more valuable than shaving time from a parallelized process like downloads. If you are looking to eek out every last bit of performance from your pages, it may be worth testing the difference on your site.

Deciding When to Use the CDN

Since I’m using such a small part of jQuery UI, there is a clear benefit from hosting a custom version instead of using the Google CDN. I’ve also explored compiling every script in the page together, but found that it only provided a small execution speedup. There are several factors you should consider when deciding whether to use a library on a public CDN, host it yourself as a separate script, or combine it with other scripts you already host:

  • Script Size – There are overhead costs for each file a browser has to request so it’s valuable to reduce the number of requests by combining files. However, its usually not a good idea to combine whole libraries (like jQuery) that are available on a public CDN.
  • Percentage Used – If you are using most of the functionality in a library, it makes sense to use the public CDN. As your use of a library decreases, it becomes more attractive to host a subset yourself. Evaluation speed improves at the cost of additional transfer (assuming the user would have the file in their cache). Experiment with the advanced optimization mode of the Google closure compiler which can remove unused code entirely.
  • Frequency of Changes – Most libraries only change every few weeks or months. If you update your site specific scripts frequently, you’ll loose much of the caching benefit if all the scripts are combined. I like to keep library and site specific scripts in separate files.

Improving jQuery UI

While writing this post I began to wonder how we could combine the benefit of jQuery UI on a public CDN while retaining the evaluation speed of a custom download. Right now, the jQuery UI library creates a custom download by only including the necessary bits. One alternative would be to allow the full library to only initialize the components a developer needs for the page. Developers could specify which pieces they want in some well known location on the jQuery object. When jQuery UI loads, it looks for the config settings. If it doesn’t find any, it follows the current behavior of initializing everything. This approach would allow everyone to use the full CDN version even if they are only using a small part of the library. It seems pretty straightforward so maybe I’ll try to code it up once I have a little free time. I’d love to hear any feedback you have on this idea.

This entry was posted in Uncategorized and tagged , . Bookmark the permalink.

Leave a comment