O'Reilly

Caching AJAX Results in JavaScript

By on  
AJAX Caching!

AJAX is an awesome tool. AJAX requests are usually faster than regular page loads and allow for a wealth of dynamism within a page. Unfortunately many people do not properly cache request information when they can. Let me show you how I cache AJAX requests -- it's super easy!

My example will use my TwitterGitter plugin to grab a user's tweets. Once we have the user's tweet information, we pull it from cache instead of making a duplicate AJAX request.

The JavaScript

//our cache object
var cache = {};
var formatTweets(info) {  
	//formats tweets, does whatever you want with the tweet information
};

//event
$('myForm').addEvent('submit',function() {
	var handle = $('handle').value; //davidwalshblog, for example
	var cacheHandle = handle.toLowerCase();
	if(cache[cacheHandle] != "undefined") {
		formatTweets(cache[cacheHandle]);
	}
	else {
		//gitter
		var myTwitterGitter = new TwitterGitter(handle,{
			count: 10,
			onComplete: function(tweets,user) {
				cache[cacheHandle] = tweets;
				formatTweets(tweets);
			}
		}).retrieve();
	}
});

Note that before we make the AJAX request, we check the cache object to see if we've saved this key's (the key, in this case, is the username because it is unique) information. If so, avoid the repetitive AJAX request and simply return the cached information. If the key does not exist, make the AJAX request and save the result to the cache.

Take a look at this flow:

  • User requests "davidwalshblog" tweets. @davidwalshblog tweets don't exist in cache, so we go grab them from Twitter and store them in cache.
  • User requests "mootools" tweets. @mootools tweets don't exist in cache, so we go grab them from Twitter and store them in cache.
  • User requests "davidwalshblog" tweets again. @davidwalshblog tweets DO exist in cache, so we retrieve them from cache and avoid the ajax request.

Clearing the cache periodically is easy too!

(function() { cache = {}; }).periodical(1000 * 60 * 10); //10 minutes

Caching your AJAX results in a JavaScript object is a very simple system to implement and can save you many repetitive requests. Efficiency FTW!

O'Reilly Velocity Conference
Save 20% with discount code AFF20

Recent Features

  • 5 HTML5 APIs You Didn’t Know Existed

    When you say or read "HTML5", you half expect exotic dancers and unicorns to walk into the room to the tune of "I'm Sexy and I Know It."  Can you blame us though?  We watched the fundamental APIs stagnate for so long that a basic feature...

  • Serving Fonts from CDN

    For maximum performance, we all know we must put our assets on CDN (another domain).  Along with those assets are custom web fonts.  Unfortunately custom web fonts via CDN (or any cross-domain font request) don't work in Firefox or Internet Explorer (correctly so, by spec) though...

Incredible Demos

  • CSS Filters

    CSS filter support recently landed within WebKit nightlies. CSS filters provide a method for modifying the rendering of a basic DOM element, image, or video. CSS filters allow for blurring, warping, and modifying the color intensity of elements. Let's have...

  • MooTools’ AutoCompleter Plugin

    One of the famous MooTools plugins is Harald Kirschner's AutoCompleter plugin. AutoCompleter takes a term input by the user and searches for matches -- an obviously help to the user. Here's how to make the most of Harald's great plugin. The XHTML All we...

Discussion

  1. It should be noted that the cache is [obviously] per-client… meaning that when visitor 1 requests ABC, it will be sent and then cached locally to their browser. When visitor 2 comes along 5 seconds later, another request to ABC will be sent, and then cached to their browser as well.

    Clearing the cache (in this case, every 10 minutes) will only be useful if the client sits on the page for ten or more minutes. If I visit your site and have an AJAX request cached… when I click to another page, even within the same website, the cache will be refreshed.

    A good practical use for this would be a JavaScript-laden web app where you know the client will be on the same page for an extended period of time.

    Great tutorial!

  2. I don’t know much about the twitter api but is it possible to grab in the last tweets within the last x minutes? That way you don’t have to clear out your whole cache and grab the content that was in the cache to begin. I think this caching idea is to a good start but I think it can be greatly improved. I don’t think this is how for example gmail caches it’s mail entries. Obviously caching tweets can only be as good as the twitter api will provide, so this might be the best caching strategy given the current api.

  3. Right Jesus, but Twitter is simply my example. You could implement this system with any site or functionality.

  4. Right, I just wanted to start a discussion about other ways to do caching :). I just looked at the twitter api and it has a since_id field that you can pass in. I’m thinking that one way we can extend this caching is to add some logic before clearing out the cache. First we ask for the last tweets using the since_id field. We concatenate the results and the delete the tail end of the tweets that are over our limit. That way we are only asking for only new tweets and not tweets we already had and only deleting the tweets that we longer want.

    I realize this was just an example and I appreciate that. I would had never brainstormed if it wasn’t for this post. Good post to start the day with.

    Adding new objects to the DOM and making sure the ajax calls are queued are now two problems that get introduced with caching. IBM has a nice article using jquery to solve these two issues using the live, die calls and queue and dequeue methods, I’m not familiar with mootools but I would assume it has similiar functionality. http://www.ibm.com/developerworks/web/library/wa-aj-advjquery2/index.html

  5. In addition to what @Keith mentioned, I would also note that the cache hash is only available until another full (synchronous) request is made, at which time the cache object is destroyed. This is about the best you can do though if you only have client side control.

    If you do have server side control of the response, though, it is definitely worth setting the appropriate headers (content-expires/cache-control/eTags…) to make the browser cache the response – which can even persist across browser sessions.

    I do like this approach though for applications that are largely asynchronous, such as Google Reader. It allows you to enforce more complex caching policies than HTTP handlers do. Good article DW.

  6. @Jeremy Martin: Yep — my new website is entirely AJAX based so this caching method comes in handy bigtime!

  7. test de prueba si moderan los comentarios.

  8. Champ

    I am pretty sure that is the AJAX cleaning solution logo… just sayin

  9. The browser’s built in cache can be leveraged as well if you understand and use cache control headers properly. Of course calling other people’s APIs may not allow for that – Demo: http://ajaxref.com/ch6/builtincache.html

    In support of custom caches you might want to implement a more full fledged cache that allows you to control # of entries, push objects to it, etc. Demo: http://ajaxref.com/ch6/customcache.html

    It has been odd for me to nearly weekly notice that queues, caches, etc. are missing still from nearly every major Ajax library out but yet it was well documented in my book 2 years+ ago. with example library code. Port away if you like otherwise cool to see other people discover clear holes in Ajax!

    -Thomas

    p.s. To a previous poster the queue and sequencing issues are also easily solved…see same site Chapter 6 examples on how performed. Your tradeoff though with queues and response buffers will be performance but your results will now nearly always work assuming you have error correction, retries, etc.

  10. What does var foo = {}; Mean? I don’t understand the {} bit. Is it a regular piece of JS?

  11. @Ben: it is shorthand for creating an object.

    var foo = []; is a shorthand method of creating an array;

  12. @Keith: {} is an empty object declaration in javascript.

  13. That’s what I said, right? :)

  14. An interesting challenge, from an academic perspective at least, would be to implement a more persistent form of caching using cookies – don’t need to modify headers, but you still get content caching across browser sessions. Probably not practical for many real life uses, but would be interesting none-the-less…

  15. @Keith: Hahaha. My bad — wrong person.

  16. Connie

    Hi,

    do I understand that correctly,
    that for instance I could cache values from a mysql query which runs to fill the autosuggest-dropdown to use these values to populate other fields of the form after the autosuggested value is accepted by the user?

  17. Supposedly a user stays on a page more than 10 minutes. Then there is a chance that the user will stay more.

    Why destroy the cache then? Why not instead, use HEAD HTTP method and see if the state of the cache is still valid? If it is still valid — keep it. No need to re-fetch the same data over and over again.

    Even better, you could set up a cron that fetches the remote data every once in a while, again using HEAD to determine whether or not indeed the cache has expired and then load the data from your local file (preferably json, since it’s kinda fast). Set the reasonable expires headers accordingly to the last modified time of the local item and the update expectancy of the remote source.

    Of course, this is far from “real time” data, but then again it saves bandwidth, cuts down server load, eliminates network related issues and thus improves user experience.

    On the other hand, if indeed real-time-like feel is required, we are talking about caching and requesting on a whole new level.

  18. gel

    btw, the wp pdf plugin don’t works :D

  19. David, what happens if the page is refreshed in this case, is the cache cleared or will it be preserved?

  20. Chad

    Hey Guys

    I get cachehandle is not defined object !! any ideas???

  21. andrei cristof

    >Great stuff. Although please explain this line:

    User requests “davidwalshblog” tweets again. @davidwalshblog tweets DO exist in cache, so we retrieve them from cache and avoid the ajax request.

    They do exist in cache yes, but the cache contains his previous tweets, in order to retrieve all his tweets PLUS the latest one, you must make a new request. Am I missing something?

    Thanks

  22. Benny

    I curious if something like this can be used for a static top bar on a web page. For instance, lets say you have a web page with a top menu bar with some content that’s specific to the user that’s logged in (shows their picture, their name, etc) and that bar is shown on each page that they view on your web site. How can one avoid needing to fetch that user specific information on each and every page load? Thanks!

  23. Hey check out my js lib for caching.

    https://github.com/hoangnd25/cacheJS

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Recently on David Walsh Blog

  • Open Files from Command Line on OS X

    I'm as much of a fan of application UIs as anyone else but I'm finding myself working more and more from the command line lately.  Much of that is becoming obsessed with media manipulation but I'm forcing myself to use less UIs so that I...

  • Get Stock Quotes From Command Line

    When I conned my way into my first professional programming gig, I didn't really think much about money -- just that I was getting my foot in the door.  But as my career has gone on, I've been more aware of money, investing, and retirement.  I've recently...

  • Geolocation API

    One interesting aspect of web development is geolocation; where is your user viewing your website from? You can base your language locale on that data or show certain products in your store based on the user's location. Let's examine how you can...

  • Create an Image Preview from a Video

    Visuals are everything when it comes to media.  When I'm trying to decide whether to watch a video on Netflix, it would be awesome to see a trailer of some kind, but alas that isn't available.  When I'm looking to download a video on my computer,...

  • New:  Webdesigner News!

    A new and exciting website has recently been launched for web designers and developers. You likely spend hours every morning browsing through hundreds of posts on your RSS feeds, hoping to stumble across relevant stories. Webdesigner News was built to provide web designers and developers with...