photo credit: Cache K4P LosAngeles Graffiti Art via photopin (license)

Make better use of Magento’s cache

Tags: ,

Magento has it’s built-in caching mechanism, but unfortunately it’s not used very often (or by default). This is good to know when you are creating a module with your own custom block templates. When you know what you are doing, the speed benefits can be pretty impressive!

Magento’s cache

Magento has different ways of applying cache. In this article I’ll cover 2 of them:

  • Caching you own custom templates.
  • Caching directly in a template (phtml) file.

Apply cache on your own custom templates

I suppose you already built a module or two, or created custom phtml template that derived from the core/template -type. so you’re already familiar with block templates. A much used approach is by adding a rule like this to your local.xml -layout file:

As you see, this template derives from the core/template -type. I common mistaken assumption is that since this is a HTML template, it’s HTML is automagically covered by the BLOCK_HTML -cache of Magento. After all, it’s a block and it’s HTML right?
If you want to make use of the BLOCK_HTML-cache you have to enable it for that specific block first. If you look at the _construct() -method of Mage_Core_Block_Template you’ll notice that there is no such thing. In fact, nearly no blocks are cached by default by Magento. Take a look at the _construct() -method in Mage_Page_Block_Html_Footer for example:

Now there’s a constructor that actually caches something! By setting the cache_lifetime  to false  it effectively sets it to infinite. If you don’t want to cache your block, you should set it to null . The cache tags determine when the cache is cleared in the backend. For example, by setting the cache tag to Mage_Catalog_Model_Product::CACHE_TAG , the cache only gets flushed when the cache of the type ‘Products’ is cleared.

Apply caching in your template files

Another more low-level but also more verbose way of handling your cache is by controlling it from within your templates. This might be handy for you own custom templates, or if you’re overriding core templates but don’t want to rewrite their relative Block classes. You can do this by generating a unique cache key for your template file and checking your cache for it:

The example above is pretty straight forward. First we create a unique cache key for our data. In this example I’m using:

  • A custom prefix, to determine the type of content we are caching (products, categories, banners, pages, news items, etc.).
  • A md5-hash consisting of some unique qualities for this page:
    • The name of the (Block) class.
    • The request parameters that were sent.
    • If the customer is logged in or not.

This unique cache key is used to load (or save) our cached HTML data. Secondly, we use PHP’s default ob_start()  and ob_get_clean()  functions to buffer and save the generated content of our HTML page.
Now this approach might look quirky at first, but I’ve managed to get speed savings with this methods that would truncate the load of a single page from 1.2 seconds to 0.4 seconds. So although this approach might not win the beauty contest, it’s results are pretty effective!

In conclusion

It doesn’t matter how you cache, as long as you make sure you’re caching the right things. Which method you use is up to you; if you’re creating your own custom module with it’s own custom blocks, it’s better if you put your caching information inside your Block class. If your rewriting template files you might be better of by caching in-place.
In both cases it’s important to know what to cache and what not to cache. Some things might be user-dependent, or rely on pagination. If you do need to cache those items, make sure to add the variables that influence the possible outcome to your unique cache key.
In some cases it might also be desired to make use of some JavaScript after the cached data is rendered. I had a situation once where the navigation took very long to load. Caching was the solution, but also the active-state in the navigation was cached. I solved it by omitting the active-state and adding it later on to the correct node with JavaScript. So sometimes you just have to be a bit creative when it comes to solving caching problems.

Visitors give this article an average rating of 3.8 out of 5.

How would you rate this article?

2 thoughts on “Make better use of Magento’s cache”

  1. Bad Form says:

    Please do not attempt to interact with Magento cache in templates. Very bad approach. Templates should never be operating on and storing data, even if it is simply output html caching. This article will teach others an incorrect solution. Bad form.

    1. Giel Berkers says:

      You’re absolutely right! I wrote this article a while ago, and I ‘forgot’ about my vision on templates when I wrote this article. It was more of a ‘quick fix’ at the time. As you state, logic should never be part of your template, and in this case the caching logic should be placed inside the block class responsible for rendering the template. I’ll update this article soon and will write a new one about the right approach for templating.

Leave a Reply