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|
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!