29
protected function _construct()
    {
        $this->addData(
            [
                'cache_lifetime' => false,
                'cache_tags' => array('MY_BLOCK'),
            ]
        );
    }

    public function getCacheKeyInfo()
    {
        return [];
    }

does not work. Why? How to disable the cache for block?

2
  • I suspect your block is inside another block that is also cached. For example, anything you put inside the footer block is cached because the footer block output is cached.
    – Smartie
    Feb 24, 2016 at 12:24
  • @Smartie how to turn it off me? <referenceContainer name="content"> <block class="class" template="block.phtml" before="product.info.main"/> </referenceContainer>
    – gebuket
    Feb 24, 2016 at 12:38

6 Answers 6

34

Blocks can be set as non-cacheable by setting the cacheable attribute false in layout XML files. For example

<block class="Block\Class" name="blockname" cacheable="false" />

Pages containing such blocks are not cached.

Also check How do disable caching of custom block

Edit: A single cacheable="false" will disable Full Page Caching for the whole page, making the pages sourcing from that layout file extremely slow! Check https://inviqa.com/blog/how-full-page-cache-works-magento-2

6
18

It's important to understand why you don't want to cache block. If this is meant to show some session specific information then you should be looking into

One non-recommended option could be also custom controller what returns some data over ajax-call (with POST-method so it wouldn't be cached).

(!) cacheable="false" must not be used. Here will follow, WHY not:

A block with cacheable="false" will make the whole page uncached. It is not used for cache hole-punching. Also older M2 docs page use to says this (To create an uncacheable page, mark any block on that page as uncacheable in the layout using cacheable="false").

New docs is saying

What it does is that Varnish/Fastly modules will be sending due this attribute value always non-cacheable headers.

When we enable cachable="false" and while using Varnish/Fastly then browser side following headers are sent :

X-Magento-Cache-Debug:MISS
X-Magento-Cache-Control:max-age=0, must-revalidate, no-cache, no-store
Age: 0

For that can be debugged the Magento's page caching code on

vendor/magento/module-page-cache/Model/Layout/LayoutPlugin.php::afterGenerateXml
vendor/magento/module-page-cache/Model/Layout/LayoutPlugin.php::afterGetOutput

where first one should send public Cache-Control with TTL and second should send X-Magento-Tags for Varnish/Fastly.

Both are using isCacheable() check where this always returns FALSE due following check (check if in current layout there are any attributes:cacheable="false"):

$cacheableXml = !(bool)count($this->getXml()->xpath('//' . Element::TYPE_BLOCK . '[@cacheable="false"]'));

When we remove cacheable="false" then we start to get isCacheable() checks as TRUE and also get headers correctly on start-/category-/productpages.

X-Magento-Cache-Control:max-age=86400, public, s-maxage=86400
X-Magento-Cache-Debug:HIT
X-Magento-Cache-Hits:1
Age:32
3
  • 1
    So... what is the alternative solution?
    – Black
    Feb 13, 2020 at 19:02
  • alternative must be taken case by case - what you need. if it's customer related then you need to define additional item-argument for Magento\Customer\CustomerData\SectionPoolInterface in etc/frontend/di.xml (ex. devdocs.magento.com/guides/v2.3/extension-dev-guide/cache/… ). if it should be block with dynamic data depending from product, then maybe it should be javascript component or widget. It really depends all on the case. Mar 5, 2020 at 6:42
  • can you please add more details about using the sectionpoolinterface? I have some custom blocks using isScopeprivate variable. But I dont know how to replace that with alternate way. can you please help Apr 23, 2020 at 10:15
16

I have made non-cacheable for Pricing block

<?php

namespace Custom\Module\Block\Pricing\Render;

class ExtendFinalPriceBox extends \Magento\Catalog\Pricing\Render\FinalPriceBox {

    public function getCacheLifetime()
    {
        return null;
    }

}
5
  • How did you replace FinalPriceBox with ExtendPriceBox using di.xml?
    – siddhesh
    Jul 14, 2017 at 14:54
  • Yes using di.xml Jul 18, 2017 at 16:39
  • @LeadDeveloper, he wants to know what you wrote into your di.xml
    – Black
    Feb 13, 2020 at 19:02
  • @LeadDeveloper this is not working Dec 4, 2020 at 10:17
  • This doesn't stop using ESI loading by varnish, and as such it doesn't get for example HTTP GET params from the parent request. May 17, 2022 at 10:24
3

Try to avoid using cacheable="false" as this disables cache for the entire page and causes performance issues.

When using Varnish you can use the ttl attribute instead, like:

<block class="Block\Class" name="blockname" ttl="0" />

1

I wouldn't recommend using cacheable="false" since it's a "page cache breaker" as it states in Magento developer docs. If you make getCacheLifetime in the block to return null it doesn't stop making ESI requests for the block and ESI requests are not going to get any of the parent page GET context like category ID, etc.

If you remove the block in the layout and re-add with different name it with current dependencies to the block. For example:


<referenceBlock name="catalog.topnav" remove="true" />
<block class="Magento\Theme\Block\Html\Topmenu" name="custom.catalog.topnav" as="catalog.topnav" template="Magento_Theme::html/topmenu.phtml" >
    <!-- Find and put here dependencies that are currently injected to the removed block -->
</block>

This way this block is not loaded by ESI and it doesn't break the page cache.

0

You can add non-cacheable block only to custom pages. In other case, magento Page Cache will not work for these pages OR update information in block via ajax (magento section requests).

1
  • this solution is not working in magento 2.4.5 Nov 8, 2022 at 13:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.