Coming Soon: Caching in SPServices

For a long time, I’ve been reluctant to try to add caching to SPServices. The main reason is that I couldn’t think of a reliable way to do it that wasn’t going to cause potential issues and it also had to be backward compatible. Well, I think I’ve cracked that nut. In the current alpha of SPServices (v0.7.2ALPHA3), I’ve implemented a caching capability.

In my SPServices development environment, I have a ridiculous page which has far more calls to SPServices than you are likely to ever implement on one page yourself. It’s the page I use to test all of the potential combinations of calls that you might ever want to make to ensure that they work consistently. My testing is certainly not always foolproof, but this page has served me well to get most of the obvious kinks out for every version since the beginning of the library. (It runs in WSS 3.0, so I start there and move up the chain to test things with cross-version capabilities.)

Just to show how ridiculous it is, here are some counts:

Function Number of Calls
SPFilterDropdown 3
SPArrangeChoices 2
SPSetMultiSelectSizes 2
SPCascadeDropdowns 3
SPLookupAddNew 5
SPDisplayRelatedInfo 4
SPAutocomplete 1

At first glance, that may not seem so bad, but it takes 47 calls to various Web Service operations, and therefore 47 AJAX calls, just to load the page. It can take anywhere from 5-8 seconds on average, though sometimes it’s far worse.

After implementing the caching capability, I’ve cut that down from 47 to 27 calls, which is a 43% reduction, if I’m doing my math right. Even better, the load time is now consistently around 3.5 seconds. (I’m timing things in Firefox because Firebug makes it easy.)

Better yet is the performance improvement I see when I start changing values in the dropdowns, which causes more calls. The way I’ve implemented this, I’m caching the results for every single unique SOAP message SPServices sends to the server. This means that I’m not trying to cache all the items in any list, but only the XML which is returned for each request. Since each request has a unique “fingerprint” in the form of the SOAP message itself, I have a key to use to store the cached XML object and a way to retrieve it. The jQuery .data() function is what powers this simple little idea.

The way this works is somewhat clumsy: you only get a benefit if you make a call that is exactly the same as a prior call. However, that’s not as uncommon as you think, especially under the covers in the value added functions like SPCascadeDropdowns and most of the others above.  Many of the value added functions must call GetList for one reason or another, and just caching those calls cuts out something like 15% of the calls in my bloated page.

Now that I’ve posted this new alpha, I *really* need some help regression testing. Right now, the caching is all or nothing. There’s a default option called cacheXML, and it’s set to true in the alpha, so everything that can be cached will be cached. (When I release this functionality for real, the option will be set to false so that nothing works differently in existing applications.)

So here’s how you can help. Download the alpha and drop it into a test environment where you are already making SPServices calls. Try some tests with the alpha as it is, and then with the cacheXML option set to false. With Fiddler or Firebug, you should be able to see the SOAP traffic and get a gauge on what sort of improvement you might be able to gain. Let me know what you see and whether you have any problems. You can pass cacheXML: false into any call to SPServices if you need to turn off the caching for that call. Try some debugging, too, because I don’t want to make anything work differently than it has in the past.

The idea is simple, but it may well cause problems I haven’t thought about. Let me know how things go as a comment to this post, or better, in the SPServices Discussions, where it’s easier to post and format code. I think you’re going to like this!


  1. Hey Marc,
    I just got into another project where I will be going back to the “Middle Tier” again :) Great to see that you have kept the SPServices going stong.

    • Balaji:

      The answer is that caching will be an option per function call which is off by default. If you want to take advantage of it, you’ll have to turn it on. Hopefully you’ll do some thinking about what it means in your particular application. I’m also thinking about adding some sort of configurable time limit on the life of any particular cached data, but I haven’t gotten to that yet. What are your thoughts?


  2. Marc,

    In my case I had a custom service where I depend on the timestamp. when users requests the same again, we use the cached data but behind the scenes make a call to the service to check if the data is changed with the cached time stamp as input, If there is a update then data is fetched or no change in UI. For eg In this case I think we can depend on the following method GetListItemChanges to see if there are any changes after the cached data.

    Just my thoughts.


    • Balaji:

      The caching I’m putting into SPServices this go round isn’t going to be that smart. My goal is to reduce the number of Web Services calls in the page lifespan, especially where there are multiple uses of the value added functions.

      In a case like yours, you’d certainly want your own custom logic. Checking the timestamp can cut down on data volume over the wire, but not on number of calls, at least generally speaking.



Have a thought or opinion?