views:

75

answers:

1

I'm just starting to look in to caching to improve performance and have a question about caching for an AJAX call.

I have a action which is used to query twitter and then return the results. At the moment when a user presses a button it loads a rotating gif whilst it goes off to the action to do the query and then return a partial view. jQuery then updates a div with the HTML response from the view. Normally this takes around 5 secs. They then have a more button which goes off to get more results.

What will happen if I put the CachingAttribute over this action? I know I can try it but I just want the technical side of things explained.

Thanks

Here is my Javascript:

$('#blogEntryList #moreLink').live("click", function() {


                $('#morespan').toggle();
                $('#loader').toggle();

                $.get($(this).attr("href"), function(response) {
                    $('#blogEntryList ol').append($("ol", response).html());
                    $('#blogEntryList #moreLink').replaceWith($("#moreLink", response));
                    $('#loader').hide();
                    $('#morespan').show();
                });
                return false;
            });

Here is my modified Action:

[OutputCache(
    Location = OutputCacheLocation.Server,
    Duration = 100,
    VaryByParam = "")]
        public ActionResult BlogPosts(int? entryCount)
        {
            if (!entryCount.HasValue)
                entryCount = defaultEntryCount;

            int page = entryCount.Value / defaultEntryCount;

            IEnumerable<BlogData> pagedEntries = GetLatestEntries(page, defaultEntryCount);

            if (entryCount < totalItems)
                AddMoreUrlToViewData(entryCount.Value);

            return View("BlogEntries", pagedEntries);
        }
+1  A: 

Here's how it works: assuming no caching specified on the server side, by default GET requests will be cached by the browser and POST requests not cached unless you specify the cache: true attribute when sending the AJAX requests which allows you to override the client caching strategy.

Now on the server side you could decorate your controller action with the [OutputCache] which will allow you to define different caching strategies. You could keep a cache on the server, on downstream proxy servers, or on the client. You could also manage different expiration policies.

So let's illustrate this by an example:

[OutputCache(
    Location = OutputCacheLocation.Server, 
    Duration = 10,
    VaryByParam = "")]
public ActionResult Hello()
{
    return Content(DateTime.Now.ToLongTimeString(), "text/plain");
}

And on the client side:

$.ajax({
    url: '/home/hello',
    type: 'post',
    success: function (result) {
        alert(result);
    }
});

The result of this controller action will be cached on the server for 10 seconds. This means that the server will be hit on each request but the action won't be executed if there's a cached version and will directly served from this cache. 10 seconds later from the first request which hit the controller action the cache will expire and the same process repeats.

Darin Dimitrov
So when the user clicks for more data in my situation it will return the 1st 10 results over and over again until the cache expiry runs out? In that case I probably wont want to use a cache because when they click for more data it cant be cached
Jon
@Jon, you can use the `VaryByParam` property to specify an action parameter name like for example the page number.
Darin Dimitrov
Can VaryByParam contain a CSV of values eg/ if you have 5 page numbers?
Jon
Try separating the parameter names by semicolon: `VaryByParam="PageNumber;StartPage;Foo;Bar"` or if you want the cache to vary by each combination of action parameters: `VaryByParam="*"`
Darin Dimitrov
Thanks. I just added caching it doent seem to be caching anything. I have added my javascript to my question. Maybe there is something wrong?
Jon
How about your controller action?
Darin Dimitrov
Now attached. I changed the javascript to post and it seemed to cache because I added a datetime to the view however it was still taking as long to return the HTML as if it wasnt cached. I thought if it was cached it wouldnt execute the action and therefore be quicker?
Jon
When an action is cached on the server it is the result of this action that's cached. This means that the server will still be hit but the code inside the action won't execute. Of course if your server is slow it won't help much.
Darin Dimitrov
Thanks after a bit more investigation it does seem to be slightly quicker. Can you answer whether my javascript needs to be post or get?
Jon
As I mentioned in my answer a GET request could be cached by the browser. In this case there won't even be a request sent to the server which might not be what you are expecting. That's a common problem with GET AJAX requests in IE.
Darin Dimitrov
Ok thanks just thought I'd get clarification. I will change to post. Interestingly I have not used the VaryByParam and it has succesffuly cached each view returned for the different page numbers. Would that be because there is only the one action parameter?
Jon