Partial Page Output Caching

Partial Page Output Caching is a new feature in ASP.NET MVC 3, and one I am really excited to see. Up until this time we were only able to output cache the entire view in ASP.NET MVC. In today's web applications where a page is often a mashup of unrelated data, partial page caching of various sections / fragments within the page is crucial to building scalable websites.

Although MVC purists might squirm a bit with the thought, the Html.Action and Html.RenderAction helpers used within the view in ASP.NET MVC allow us to call back into the application and grab fragments of data that are often unrelated and of a separate concern than the main request. It is within these child action requests where we display these page fragments and can often take advantage of agressive caching to avoid database calls, web service calls, and other resource intensive operations.

With Partial Page Output Caching we can now decorate our child actions on the controllers with an [OutputCache] Attribute and cache those partial page fragments on a fragment by fragment basis.

An easy way to demonstrate the partial page output caching feature in ASP.NET MVC 3 is by simply displaying the current time in both the main view and a partial view requested by an Html.Action or Html.RenderAction. Here is an example of such a view. I display the current time in this view and then use Html.RenderAction to request a partial view that also displays the current time.

Partial Page Output Caching ASP.NET MVC 3

Here is the partial view, CurrentTime.cshtml, that also displays the current time:

OutputCache Attribute in ASP.NET MVC 3

As I hope you would expect, with no output caching the time in both the main view and partial view are identical. With each request, both actions are called and the requests are fast enough so that the time is the same.

However, let's turn on partial page output caching for 10 seconds on the child action using the [OutputCache] Attribute. This is the action called by Html.RenderAction within the main view with output caching turned on.

OutputCache Attribute

Now that the results of this child action are cached for 10 seconds ( i.e. this action doesn't get called again until the cache expires ), the time shown in the page fragment does not always equal the time in the main view. Hitting refresh on the browser quickly as shown in the picture below, you can see that the current time displayed by the page fragment is a time from the past when it was last cached ( 5 seconds ago ), and it won't change again until the cache expires.

Caching in ASP.NET MVC 3

If instead of displaying the time you were displaying results from a complex database query that did not change often, this partial page output caching would be a huge resource saving feature.

Known Bug Using CacheProfile with Child Actions

A good practice when using output caching is to use a CacheProfile in your web.config. This way if your caching needs change, you can easily make those changes in your web.config without having to recompile your application, etc. A typical use of CacheProfile on the [OutputCache] Attribute looks like this:

CacheProfile Child Actions in ASP.NET MVC 3

I'll save you some time here by telling you this doesn't work in ASP.NET MVC 3. There is a known bug when using the CacheProfile with Child Actions, so you will need to stick with specifying the cache directives on the attribute.

Conclusion

With ASP.NET MVC 3 we now have partial page output caching so use the [OutputCache] Attribute on your child actions wisely to help scale your web applications.

Hope this helps.

David Hayden