Magento block caching

Featured Image

Recently we were working on speeding up parts of client site which had usual problem of slow page loading caused by complicated configurable products. To solve the problem we were experimenting with extending core Magento caching capabilities.

Magento has built in predifined system of block output caching. Its block abstract has Zend_Cache caching capabilities that can be modified for your own needs. I’m showing here an example of caching whole product view block, however this is just a specific example of how things works, problems are different and requires different approach and solution.

I will start with some external reading and example itself. There is great article on Magento Wiki about this topic, along with category cache example on Magento forums.

With my Inchoo_BlockCaching.rar example module things should be little easier to understand.

Magento block caching depends of three things:
cache_lifetime => cache lifetime in seconds
cache_tags => cache type identifiers primarly used for deleting right cache at the right time
cache_key => cache identyfier

You can simply inject this data into construtor of any Magento block

protected function _construct()
{
$this->addData(array(
'cache_lifetime' => 3600,
'cache_tags'     => array(Mage_Catalog_Model_Product::CACHE_TAG),
'cache_key'      => $this->getProduct()->getId(),
));
}

or if you need some conditional approach like i did in this example define equivalent functions

public function getCacheKey(){}
public function getCacheLifetime(){}
public function getCacheTags(){}

because constructor approach isn’t enough in most scenarios.

There is a general misassumption about cache_lifetime. If you set it to false, Zend cache will get default value of 7200 seconds!! If you want infinite never expired cache set it to 9999999999, which is Zend_Cache maximum value, or something else big enough.

I believe that best way to activate this is to rewrite specific block with our own with caching enabled, like shown in example. You should always try to avoid modifying core files, even copying modified Mage classes to local, because things get really messy on updates.

Generated cached files can be found in usual subfolders of /var/cache folder. Two files are generated, first metadata file which contains serialized cache data and second one which is cached html output itself.
In my example:
mage—internal-metadatas—PRODUCT_INFO_STORE+ID_PRODUCT+ID
mage—PRODUCT_INFO_STORE+ID_PRODUCT+ID

Note that “Blocks HTML output” option needs to be enabled in Cache Management for this to work.

Many things in Magento can be cached in similar way and there are predefined mechanism waiting for you to use them. It’s possible that we’ll see more of this implemented in future Magento versions.

31
Top

Care to rate this post?

Author

Ivan Weiler

Technical Educator and Consultant

Ivan is a Technical Educator and Consultant. He gained lots of experience managing some of the most complex Magento projects we had at Inchoo.

Other posts from this author

Discussion 31 Comments

Add Comment
  1. Thanks for this blog post. My product options were being shown twice when cached but the code that you provide in the RAR file, shows how to prevent child blocks being cached which did the trick.

  2. Thanks man, I’ve been looking for this solution for a while. This sped up our site more than anything else we have tried.

  3. Another great article from the inchoo and ActiveCodeline teams.

    I’ve been having a problem with using CacheKey on my Navigation.php (customized to use an image-based nav). With cache disabled, I can see the cache key is unique as per the criteria that I set, but as soon as the cache is enabled, the content is duplicated where it shouldn’t be. Very annoying…

  4. Hi,

    can this be done via XML files by just adding some parameters or actions to a block?

    thanks, Jakub

  5. Ben

    @Jakob -

    It seems that it can be set:

    1

  6. Ben

    Had a feeling that would happen…

    @Jakob -

    It seems that it can be set:

    |block type=”whatever/block”|
    |action method=”setCacheLifetime”|
    |num|1|/num|
    |/action|
    |/block|

  7. Hi Ben, thank you for your message. I will try it how it works. It is great if it will work. Anyway I don’t know if it would be possible to set cache keys in XML.

  8. Do we just upload that rar folder and that’s it. Do we need to do anything else.

  9. Kevin

    Hello…I have been looking for a solution like this for weeks. We have over 100 configurable products and each has about 400-600 simple products associated with it. It takes literally 30-40 sec before the page load with the two drop down options. The problem is how and where should I apply this solution??? Any advise will be greatly appreciated.

  10. Hi Kevin,

    I recomend you this free catalog cache extension: http://www.magentocommerce.com/magento-connect/netresearch/extension/2138/catalogcache

  11. Saurabh

    Hi,

    We have hosted magento on 2 server with one website for testing and another website for live. Both of these share same server and same memcache.

    We have created a block which shows Recommended products. Now, we we remove some product from recommended product it reflects on one server and not on another server.

    What is the reason for this happening

    Thanks & Regards,
    Saurabh

  12. Sean

    So, how do we do the opposite, in this instance, exclude a dynamically created menu block from being cached. It would be nice to punch a hole in the static content so the dynamic content can function.

  13. Sean, Block-level caching is great, but the more you cache, the faster things move. We do have hole-punching built-into our full-page caching module – Lightspeed

    Product Page – http://www.tinybrick.com/magento-modules/performance/improve-magentos-slow-performance.html/
    Inchoo Review – http://inchoo.net/tools/magento-lightspeed-module-review/

  14. Jack

    thank u for the post. I unziped the file and uploaded it into the server…and it doesnt change anything for me. appart from uploading the files, do I need to do something else?

  15. How can I disable cache for specific child block, when parent block uses caching?

  16. sean

    Here’s how you can do that for the navigation menu (dynamic menu elements break when cached). It would be similar for anything else.

    http://www.magentocommerce.com/boards/viewreply/284834/

  17. Max

    I realised that Magento runs smoothly on any Linux servers. But when it is on a windows server using IIS, it tends to be very slow. As in apache running on windows server. Is there any solutions to slowness? a click to a product may take 10 seconds or more.

  18. @Max: Magento doesn’t support Win, see http://www.magentocommerce.com/system-requirements

  19. Max

    @WebFlakeStudio: Thanks for the information, but still magento is running on Apache. It works. Just that it is so laggy.

  20. Sean

    Running Magento under Apache using a PHP DSO module on Linux has major performance issues. In order to not consume excessive clock cycles and memory, we ended up going to using the PHP interpreter being executed under FastCGI. The final performance enhancer was ditching Apache all together and redeploying with LiteSpeed running lsphp5 for our HTTP server.

    Not sure how this translates to Apache on Windows, but getting php out of the web server is paramount to getting any performance out of Magento.

  21. Andrew

    Has anyone had problems with Magento HTML block cache causeing certain blocks to appear twice. More specifically, its our footer block.

  22. xbb

    @Andrew : Maybe a block is using the wrong cache data because of similar cache key. It often happenend to me whes I had several block classes extending the same parent.
    Check the cache_key (or function getCacheKey() ) and make it more specific if needed, using prefixes or getNameInLayout() for example.

  23. Sam

    We face the same issue (1.6.1) within the footer block Magento shows the wrong cache. Although we use the standard footer block and we haven’t changed the code there…

  24. I guess Inchoo’s readers will love our new free and open-source extension that automatically caches many blocks (and even the whole homepage content) and lets add any other block thanks to a user-friendly admin interface!

    Please feel very free to install and use.
    See : http://www.magentocommerce.com/magento-connect/soon-advancedcache-une-boutique-plus-rapide-2351.html

    And for French readers of this post, you can read a complete user’s guide at :
    http://blog.agence-soon.fr/magento-une-boutique-plus-rapide-avec-soon_advancedcache/

    I hope your Magento will now be blazing fast!

  25. Nick

    I am currently struggling with a problem – my store cms pages and categories seem to load very fast , on the contrary though I am having some issues when clicking on a product. It takes quite a while to open. I want to specify here that all my store’s products are configurable. Is there a way that I can use this method and implement it in my product view to eventually speed things up?

    Some advise would be appreciated. Thank you!

  26. Roberto Castillo

    Thank you very much, it works perfectly, i just did the opossite, i want to disable the caché for a dynamic block, and i just did this:

    protected function _construct()
    {
    $this->addData(array(
    ‘cache_lifetime’ => -1,
    ‘cache_tags’ => array(Mage_Catalog_Model_Product::CACHE_TAG),

    ));
    }

  27. The easiest method for enabling cache for a block is using the XML:

    Simply add the following to your XML:
    <action method=”setCacheLifetime”><lifetime>7200</lifetime></action>

    It now uses the name of the block as identifier, so it probably ‘just works’

  28. To expand on my above comment. By default the key is autogenerated by the following variables:

    Store code + Template file name + Template file contents

    From this information an SHA1 has is created and that is used for the cache key.

    If you have blocks that you configure yourself, please define a cache key yourselves:

    >action method=”setCacheKey”<>key<home-stores>/key<>/action<

  29. ed

    The code works fine. However, once a user purchased a product, the inventory will be updated in the backend. However, the cache of the product is not clear/updated. Any way to solve this? Otherwise this speed gain is of not much use.
    Thx a lot for help.

  30. sriram

    Hi,
    what is the difference between full page caching and block cache ? If i use both then which layer falls first level of caching ?

Add Your Comment

Please wrap all source codes with [code][/code] tags.
Top