Back in the days of Web Forms, there were two main ways of implementing caching in Umbraco. You could cache the parts of the pages that were macros using the Umbraco marco caching features, or you could use the built in ASP.Net control and page level caching features (which perform slightly better than the Umbraco ones).
Now that Umbraco support MVC views, you no longer have the option to specify page level caching in your page templates like you could in the header of your web forms master templates, where you could add something like this to your master pages:
<%@ OutputCache Duration="60" VaryByParam="None"%>
You can't specify caching within a view itself, you either have to use the caching when you render a partial macro, which you can do using Umbraco or you have to use an OutputCache directive on your action controllers.
Recently I worked on a site in Umbraco 6 where there were about five or six news/blog sections, each with their own RSS feeds, and then there was a master RSS feed in the root of the site that aggregated them all. The RSS feeds were pretty popular, so I really wanted to cache them for around 60 seconds, to help boost performance.
Using Umbraco partial caching, I'd have had to create a partial to render the RSS, and then had an "outer" view that loaded the partial and applied the caching, which I wasn't keen on, I'd rather cache the whole thing. Enter route hijacking in Umbraco. What is route hijacking? It gives you the ability to create your own controllers that will handle DocTypes and also Templates in a custom manner. As these allow you to override the ActionResult, that means you can apply an output caching directive to those templates.
So, in my example site, I have a Document Type called "RssFeed" that I would like to implement caching on for the WHOLE template. How would I do this? It's REALLY easy.
In my extensions project for my site (which contains all of my custom models, logic and helper methods), I added a class called "RssFeedController" with the following code:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.Mvc; using Umbraco.Web.Models;
namespace MySite.UmbracoExtensions.Controllers { public class RssFeedController : Umbraco.Web.Mvc.RenderMvcController { [OutputCache(Duration = 60)] public ActionResult Index(RenderModel model) { return base.Index(model); } } }
Note, that the name of the controller is very important, it should be the name of the DocType, with all spaces etc removed, followed by the word "Controller". So if your page was called "Awesome Feed" the class name would be "AwesomeFeedController". Notice the OutputCache declaration, all I'm doing is spcifying that the output should be cached for 60 seconds. There's no need to vary the cache, as the feeds can't be altered by the querystring or by user etc.
Compile the code and add the DLL to your site and it should be up and running! All Your RSS feeds are now cached for 60 seconds, and the best part is, they're cached by path, so each of the separate feeds is cached independantly.
This is only a very basic example, you can do a lot more with this, like vary the cache by parameters, specify whether the content should be cached locally or on the server, and even set different options for other allowed templates for the same DocType.
You can find out more about route hijacking in the Umbraco docs, and more detailed information on how output caching works in MVC on the MSDN. I hope this proves useful to someone :)
Instead of OutputCache I'm using Donut Caching (http://mvcdonutcaching.codeplex.com/). It's also part of the Hybrid Framework: http://our.umbraco.org/projects/developer-tools/hybrid-framework
Sweet, that looks interesting, I shall check out that project :)
Found this article to be super useful! I've been thinking about something like this for few days, and I knew about route hijacking, but I couldn't 1+1 myself.
Anyways, results are kind of underwhelming. Umbraco with all the partials cached resulted ~50 requests / sec maximum on 2ghz server. With OutputCache, it's ~100 requests / sec. Sure it's nice, but how do I even get my thousands?! Why is it so slow?
UPDATE: after doing things right, OutputCache performance went up to 400-700 hits / second. Looks good enough.