Caching JavaScript on Your Terms

Published 19 July 09 09:34 AM | jacobl 

Browsers tend to do what they like with your static content: deciding what to cache and when to refresh. On the server-side, you can specify that certain file types have a designated TTL (time to live) and that works in many cases. There are other cases when you either don't have access to the server's configuration or you need to make sure everyone has the latest bits of JavaScript.

With every release of VizitSP, our SharePoint Document Viewer, we need to make sure that users get all of the changes we've made. To achieve this, there's a very easy trick that can keep our files cached exactly as long as they need to be and it involves le query string.

What the HTTP Caching Specification Says

ThinkVitamin posted an article about the correct way to pull off browser caching while playing by the rules. This is a great way of doing things; and, if you control the server your site is running on, please do that; however, if you're a component or an installable product like our Vizit, you might not be offered that liberty.

According [to] the letter of the HTTP caching specification, user agents should never cache URLs with query strings. While Internet Explorer and Firefox ignore this, Opera and Safari don’t - to make sure all user agents can cache your resources, we need to keep query strings out of their URLs.

Supporting only IE and Firefox didn't sound that attractive to me, so I decided to do a bit of research. Digging around the net, I found out that Safari stores its cache in

   1: C:\Documents and Settings\[username]\Local Settings\Application Data\Apple Computer\Safari\cache.db

It's a SQLite database, so a quick download of the free Sqlite3Explorer tool made querying this very easy.

   1: sqlite> select request_key from cfurl_cache_response LIMIT 735,5;
   2: http://graphics8.nytimes.com/js/app/lib/NYTD/0.0.1/tooltip.js
   3: http://graphics8.nytimes.com/images/global/icons/feed_icon_16x16.gif
   4: http://graphics8.nytimes.com/js/app/analytics/gw.js?csid=H07707
   5: http://graphics8.nytimes.com/js/app/analytics/revenuescience.js
   6: http://graphics8.nytimes.com/js/app/analytics/controller_v1.1.js

What do we have here? A static file (js extension) with a query string in Safari's cache.

This got me thinking about Opera and Chrome... luckily, they make it trivial to browse their cache using the about:cache URL. This is what I found:

Chrome
chrome

tmpCD26
opera

Cool huh? It appears as though IE, Firefox, Safari, Opera, and Chrome ignore this bit of the spec and I'm OK with that.

Versioning Your Static Content

It's important that you update your version query string parameter with every release or this technique wont work. With Vizit, we do it as part of our build process. Everywhere in the code that includes a JavaScript file we append '?ver=VIZIT_VERSION'. At build time, we sift through all the files and replace that with the version number of our assemblies. Very nice indeed.

Results

On its first load with an empty cache, an upcoming release of VizitSP weighs in at about 420 KB. That small size is achieved through CSS image spriting, JavaScript compression, concatenation, and the SharePoint Web Front Ends gzipping it all; however, a second load will see that size drop to a measly 75 KB. Compare that to the New Your Times homepage which weighed in at 763 KB on first load, only dropping to 370 KB after cached. While the New York Times is a news site which means much more of it needs to be refreshed all the time, taking advantage of the fact that Vizit can update at will makes for a very nimble and fast-loading web application.

Comments

# Twitted by halhelms said on July 27, 2009 8:54 AM:

PingBack from http://realurl.org/twitted.php?id=2869444266

Anonymous comments are disabled