Magento block caching

Magento block caching

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.

You made it all the way down here so you must have enjoyed this post! You may also like:

Using Redis cache backend and session storage in Magento Marko Martinovic
Marko Martinovic, | 43

Using Redis cache backend and session storage in Magento

Magento (How to fix): One or more of the Cache Types are invalidated: Blocks HTML output. Tomas Novoselic
, | 83

Magento (How to fix): One or more of the Cache Types are invalidated: Blocks HTML output.

Super easy universal Magento cache extension Srdjan Stojiljkovic
Srdjan Stojiljkovic, | 14

Super easy universal Magento cache extension

33 comments

  1. Thank you for your post.I am modifying your code to create custom cache for Catalog pages. But it doesn’t work with enabling full page cache in enterprise version.

    Here is our issue. I thought your code can be used to fix this issue.

    Magento enterprise edition loads pages from cache without considering device. If I take a catalog page on Ipad, same design will display on mobile(even though we have different design for mobile). When I disable full page cache catalog pages works fine.
    When I searched through forums, it says its due to magento full page cache and we need to pass getCacheId with custom string for the pages.

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

  3. 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.

  4. 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<

  5. 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’

  6. 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),

    ));
    }

  7. 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!

  8. 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!

  9. 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…

  10. @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.

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

  12. 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.

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

  14. 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.

  15. 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?

  16. 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.

  17. 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

  18. 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.

  19. 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.

  20. 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|

  21. 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…

  22. 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.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.

Tell us about your project

Drop us a line. We'd love to know more about your project.