Pay attention to the evaluation cost of scripts. If you are only using a small piece of jQuery UI, then it may be better to host a custom version rather than using the full version on Google’s CDN.
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
Evaluation Occurs on Every Page View
Full jQuery UI Example
To illustrate, we’ll look at some of the scripts loaded by a typical product page on FilterPlay:
|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.