Skip to content

Commit f30864e

Browse files
authored
Cache the results of isCacheable calls to improve performance
This function call is relatively expensive when $elements has the full layout in it. Especially the PageCache module is calling this function a lot from the following places: - Magento\PageCache\Model\Layout\LayoutPlugin - Magento\PageCache\Observer\ProcessLayoutRenderElement On my local machine I've seen the impact to be anywhere between 20-40 milliseconds, when the page has been loaded a few times to warm up cache (config, block, layout, etc...), but FPC is circumvented. We could also opt to move this to the PageCache module, but I think it is ok to optimize this within the Layout class within the framework.
1 parent a6933f3 commit f30864e

File tree

1 file changed

+18
-9
lines changed

1 file changed

+18
-9
lines changed

lib/internal/Magento/Framework/View/Layout.php

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,11 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
193193
*/
194194
private ResponseHttp $response;
195195

196+
/**
197+
* Property used to cache the results of the isCacheable() method.
198+
*/
199+
private bool|null $isCacheableCache = null;
200+
196201
/**
197202
* @param ProcessorFactory $processorFactory
198203
* @param ManagerInterface $eventManager
@@ -1138,18 +1143,22 @@ protected function _prepareMessageGroup($messageGroups)
11381143
*/
11391144
public function isCacheable()
11401145
{
1141-
$this->build();
1142-
$elements = $this->getXml()->xpath('//' . Element::TYPE_BLOCK . '[@cacheable="false"]');
1143-
$cacheable = $this->cacheable;
1144-
foreach ($elements as $element) {
1145-
$blockName = $element->getBlockName();
1146-
if ($blockName !== false && $this->structure->hasElement($blockName)) {
1147-
$cacheable = false;
1148-
break;
1146+
if (!isset($this->isCacheableCache)) {
1147+
$this->build();
1148+
$elements = $this->getXml()->xpath('//' . Element::TYPE_BLOCK . '[@cacheable="false"]');
1149+
$cacheable = $this->cacheable;
1150+
foreach ($elements as $element) {
1151+
$blockName = $element->getBlockName();
1152+
if ($blockName !== false && $this->structure->hasElement($blockName)) {
1153+
$cacheable = false;
1154+
break;
1155+
}
11491156
}
1157+
1158+
$this->isCacheableCache = $cacheable;
11501159
}
11511160

1152-
return $cacheable;
1161+
return $this->isCacheableCache;
11531162
}
11541163

11551164
/**

0 commit comments

Comments
 (0)