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?
-
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– Smartie2016年02月24日 12:24:01 +00:00Commented 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– gebuket2016年02月24日 12:38:03 +00:00Commented Feb 24, 2016 at 12:38
6 Answers 6
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
-
27This is very inappropriate, a single cacheable="false" will disable Full Page Caching for the whole page, making the pages sourcing from that layout file extremely slow!Dmitri Sologoubenko– Dmitri Sologoubenko2016年11月01日 10:49:49 +00:00Commented Nov 1, 2016 at 10:49
-
2It's correct that it will disable cache for the whole page and already mentioned in the url I've shared magento.stackexchange.com/a/93473/9169. If you have a different approach feel free to share it as a new answer.amitshree– amitshree2016年11月01日 15:52:35 +00:00Commented Nov 1, 2016 at 15:52
-
Read this article, great explanation: inviqa.com/blog/how-full-page-cache-works-magento-2Dmitri Sologoubenko– Dmitri Sologoubenko2016年11月01日 20:04:45 +00:00Commented Nov 1, 2016 at 20:04
-
Awesome solution. Work like charm.Jalpesh Patel– Jalpesh Patel2018年02月13日 11:44:19 +00:00Commented Feb 13, 2018 at 11:44
-
2That's a bad idea for performance. =(Kirby– Kirby2018年07月02日 17:52:07 +00:00Commented Jul 2, 2018 at 17:52
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
Blocks that can’t be cached should be marked as non-cacheable in the layout. However, be aware that adding a non-cacheable block to a page prevents the full page cache from caching that page.
https://devdocs.magento.com/guides/v2.4/extension-dev-guide/cache/page-caching/private-content.html
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
-
1So... what is the alternative solution?Black– Black2020年02月13日 19:02:14 +00:00Commented 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\SectionPoolInterfaceinetc/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.Elvin Risti– Elvin Risti2020年03月05日 06:42:29 +00:00Commented 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 helpDivya Muralidharan– Divya Muralidharan2020年04月23日 10:15:45 +00:00Commented Apr 23, 2020 at 10:15
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;
}
}
-
How did you replace FinalPriceBox with ExtendPriceBox using di.xml?siddhesh– siddhesh2017年07月14日 14:54:51 +00:00Commented Jul 14, 2017 at 14:54
-
Yes using
di.xmlMahendra Jella– Mahendra Jella2017年07月18日 16:39:31 +00:00Commented Jul 18, 2017 at 16:39 -
@LeadDeveloper, he wants to know what you wrote into your di.xmlBlack– Black2020年02月13日 19:02:55 +00:00Commented Feb 13, 2020 at 19:02
-
@LeadDeveloper this is not workingManisha Vasani– Manisha Vasani2020年12月04日 10:17:34 +00:00Commented 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.Grzegorz Krauze– Grzegorz Krauze2022年05月17日 10:24:33 +00:00Commented May 17, 2022 at 10:24
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" />
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.
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).
-
this solution is not working in magento 2.4.5Jigs Parmar– Jigs Parmar2022年11月08日 13:35:56 +00:00Commented Nov 8, 2022 at 13:35