Improving performance with custom cache keys in Sitecore

Out of the box Sitecore offers you a considerable amount of usable cache keys to improve the speed of pages served from your platform. The standard provided cache keys are quite powerful in optimising the user experience. The image below shows how we can setup a rendering to be cached based on the page it’s served at:

We selected the checkbox ‘Cacheable’ so the rendering knows it can be served from cache. With no other options selected this rendering will be rendered once from the Controller logic and View and from that point on will be served from the cache as it was rendered the first time. This is cool for renderings that only have one appearance like for example a logo on a single website platform. When you want to start varying the renderings based on other parameters like ‘data’ (the page the data is displayed at), you will notice that Sitecore generates different cache keys to serve this data.

For example:

  • We have a ‘ImageSlider’ (rendering) with the options ‘cacheable’ and ‘vary by data’ activated.
  • We place this rendering on 2 pages in Sitecore.
  • We select the same datasource for both renderings, called ‘Slider1’ with the appropriate data we want to display

Now on those two pages the rendering is placed on, Sitecore will generate a cache key looking something like this:
#ImageSlider_#data:/sitecore/content/websitename/SharedContent/ImageSliders/Slider1

Sitecore now renders this ‘ImageSlider’ once and for the other page it generates the same cachekey, resulting in serving the same html from cache.

For one of our customers we run a multi-site setup with some customisations regarding datasources. You can read more about our customisation here and specifically check ‘Queryable Datasource’. Because we made a modification to Sitecore, in our case the ‘vary by data’ option was not working as Sitecore doesn’t recognize our datasource as a correct datasource. This resulted in renderings that all got cached on the same key, even though we gave them our own custom datasource (which was valid for us).

Example:

With the following datasource:

Which enables us to setup standard templates for websites on our multi-site platform with queryable datasources, which can be very powerful.
Now with this customization we also needed our own specific variable datasource option to enable caching to the footerblocks:

Here you can see I created our own cache key called ‘VaryByDataSource’ which will retrieve the correct datasource and add it to the cache key and in turn enables us to cache this rendering. This is just an example of a custom cache key, and we also created some other cache keys like ‘VaryByWebsite’, ‘VaryByProduct’ and ‘VaryByCategory’. The vary by website cache key is very powerful when you want to make sure a rendering is always uniquely rendered on a website. Maybe your own platform requires some of these unique custom caching keys? It’s very easy to create your own actually!

Step 1:

Expand the inherited ‘Cache’ template with ID ‘{E8D2DD19-1347-4562-AE3F-310DC0B21A6C}’. You can create some new checkbox fields there, that will make sure you can select the option on all of your Controller Renderings.

Step 2:

Create a new class called ‘GenerateCacheKey’ somewhere in your solution. Make sure it’s built and available in the assembly folder of your application. Below you find an implementation (dev) that we created. The VaryByWebsite could be useful in your own scanario.

Step 3:

Override the ‘GenerateCacheKey’ class that Sitecore MVC is using to generate a cache key for a rendering:

You will notice, that for custom logic, it will be a very good idea to really think ahead about which factors have to modify the cache keys (for a rendering) to make sure you can benefit from caching without sacrificing functionality.

 

Queryable datasource on sublayouts (presentation details)

Offcourse we all know that there is a way to set queryable datasources to sublayout definitions in the Sitecore database to help us select appropriate data for our renderings. This can be done using a module that you can find on the marketplace:

http://sitecoreblog.blogspot.nl/2012/06/datasources-queryable.html

This module – when you specify a sitecore query – changes the rendering datasource to a new location. This can be very handy when you work with the page editor and want content of specific items to be placed underneath the content item itself. You can then for example place a “/content” folder underneath your items to hold the specific content that will be displayed on your item.

What I’ve noticed during development of a new Sitecore website that uses the page editor is that it can be very handy to have a complete page setup for our content editors so they see how a page should look. Giving the editors the ability to change existing layout is generally more appreciated than giving them a blank page that they have to fill from scratch everytime they add a new page / content item.

To achieve this goal we create a new “branch” for this set of items that will help our editors to quickly fill a new content item. This branch could for example have the following structure:

2014-08-04_1224

What you see here is a branch on which we have filled specific content items and other data template based items that will be used in our branch. When the content editor creates a new item from this branch, we wanted the presentation details of this branch to have those items preselected without having them  central /in a shared folder somewhere in Sitecore. Every branch would then create this structure and the item created would have it’s own items underneath that would be used in the presentation. This offcourse could be done with the same concept as we’ve seen before in the Queryable Datasource. We went to see how Sitecore actually determines what item to present in a sublayout and found out we could play a little with the “ProcessContextQuerySource” pipeline.

We did the following: (after decompiling the Sitecore.Kernel.dll)

  • Create a new processor definition in the config that replaces the ‘Sitecore.Pipelines.InsertRenderings.Processors.AddRenderings, Sitecore.Kernel’ pipeline.

  • Create a class that inherits “Sitecore.Pipelines.InsertRenderings.Processors.AddRenderings” and implement it using the following code:

Now when sitecore is adding renderings to the page and finds a rendering that has a query: in the datasource  it will be picked up as a special rendering. This class will extract all renderings with “query:” in it’s datasource and sets the appropriate datasource for those renderings. Pretty neat huh?

You can now add a sublayout on your branch item with the following query to set default text:

2014-08-04_1225

When the item is created from the branch it will initially point to the item underneath itself, but the content editor is free to change to another datasource if needed. When you click the ‘set associated content’ button the usual stuff will happen, making sure that you can set different content as datasource.

I do realise that this concept is taken from the queryable datasource, tho I think that this might be useful to setup a branch with item specific data underneath the content item itself (without having to create shared content items somewhere to point at from the datasource).

That’s it for now!