Website speed is crucial for eCommerce success. A slow website can drive customers away, while a fast one improves user experience and boosts conversions. One effective way to enhance Magento 2 performance is by implementing a custom cache type. This allows you to cache specific content, reducing load times significantly.
In this guide, we’ll walk through the process of creating a custom cache type in Magento 2, integrating it into the frontend, and optimizing page performance.
Why Use a Custom Cache Type in Magento 2?
Magento 2 has a built-in caching system, but a custom cache type is beneficial for functionalities like a MegaMenu. Benefits include:
- Faster load times by caching specific content.
- Simplified cache management in the Magento admin panel.
- Reduced server processing and improved scalability.
Implementing this solution resulted in a nearly one-second improvement in page load time, which enhances both user experience and SEO rankings.
Step 1: Creating a Magento 2 Module
Before adding caching, we need to create a module.
Register the Module
File: app/code/VendorName/ModuleName/registration.php
<?php
use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(
ComponentRegistrar::MODULE,
'VendorName_ModuleName',
__DIR__
);
Define the Module Configuration
File: app/code/VendorName/ModuleName/etc/module.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="VendorName_ModuleName" setup_version="1.0.0"/>
</config>
Step 2: Creating a Custom Cache Type
To define a new cache type, create a cache.xml
file in your module.
Create cache.xml
File: app/code/VendorName/ModuleName/etc/cache.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Cache/etc/cache.xsd">
<type name="megamenu" translate="label,description" instance="VendorName\ModuleName\Model\Cache\Type">
<label>Megamenu</label>
<description>Megamenu Custom Cache </description>
</type>
</config>
Create the Cache Type Class
File: app/code/VendorName/ModuleName/Model/Cache/Type.php
<?php
namespace VendorName\ModuleName\Model\Cache;
class Type extends \Magento\Framework\Cache\Frontend\Decorator\TagScope
{
const TYPE_IDENTIFIER = 'megamenu';
const CACHE_TAG = 'MEGAMENU';
public function __construct(\Magento\Framework\App\Cache\Type\FrontendPool $cacheFrontendPool)
{
parent::__construct($cacheFrontendPool->get(self::TYPE_IDENTIFIER), self::CACHE_TAG);
}
}
This adds the Megamenu cache type to the Magento Cache Management page.
Step 3: Implementing the Cache Helper
The cache helper will handle loading and saving cached content.
Create the Cache Helper
File: app/code/VendorName/ModuleName/Helper/Cache.php
<?php
namespace VendorName\ModuleName\Helper;
use Magento\Framework\App\Helper\AbstractHelper;
class Cache extends AbstractHelper
{
const CACHE_TAG = 'MEGAMENU';
const CACHE_ID = 'megamenu';
const CACHE_LIFETIME = 31536000;
protected $cache;
protected $cacheState;
protected $storeManager;
private $storeId;
public function __construct(
\Magento\Framework\App\Helper\Context $context,
\Magento\Framework\App\Cache $cache,
\Magento\Framework\App\Cache\State $cacheState,
\Magento\Store\Model\StoreManagerInterface $storeManager
) {
$this->cache = $cache;
$this->cacheState = $cacheState;
$this->storeManager = $storeManager;
$this->storeId = $storeManager->getStore()->getId();
parent::__construct($context);
}
public function getId($method, $vars = [])
{
return base64_encode($this->storeId . self::CACHE_ID . $method . implode('', $vars));
}
public function load($cacheId)
{
if ($this->cacheState->isEnabled(self::CACHE_ID)) {
return $this->cache->load($cacheId);
}
return false;
}
public function save($data, $cacheId, $cacheLifetime = self::CACHE_LIFETIME)
{
if ($this->cacheState->isEnabled(self::CACHE_ID)) {
$this->cache->save($data, $cacheId, [self::CACHE_TAG], $cacheLifetime);
return true;
}
return false;
}
}
Step 4: Caching the Top Menu
To use the cache in the top menu, create a block class.
Create the Block Class
File: app/code/VendorName/ModuleName/Block/Html/CacheMenu.php
<?php
namespace VendorName\ModuleName\Block\Html;
use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Element\Template\Context;
use VendorName\ModuleName\Helper\Cache;
class CacheMenu extends Template
{
protected $cachehelper;
protected $customArgument;
/**
* Constructor for custom block
*
* @param Context $context
* @param Cache $cachehelper
* @param string customArgument
* @param array $data
*/
public function __construct(
Context $context,
Cache $cachehelper,
$customArgument, // Argument passed from layout XML
array $data = []
) {
parent::__construct($context, $data);
$this->cachehelper = $cachehelper;
$this->customArgument = $customArgument;
}
/**
* Override the getHtml() method to modify top menu output
*
* @param string $outermostClass
* @param string $childrenWrapClass
* @param int|null $limitItems
* @return string
*/
public function _toHtml()
{
//$cacheId = $this->cachehelper->getId($this->getData('custom_argument'))."-".$this->getData('custom_argument');
$cacheId = strtoupper($this->getData('custom_argument'));
if($cache = $this->cachehelper->load($cacheId)){
return $cache;
}
$html = parent::_toHtml();
$this->cachehelper->save($html, $cacheId);
return $html;
}
}
Modify the Layout File
File: app/code/VendorName/ModuleName/view/frontend/layout/default.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<!-- Override topmenu_desktop block -->
<referenceBlock name="topmenu_desktop" class="VendorName\ModuleName\Block\Html\CacheMenu">
<arguments>
<argument name="custom_argument" xsi:type="string">topmenu_desktop</argument>
</arguments>
</referenceBlock>
<!-- Override topmenu_mobile block -->
<referenceBlock name="topmenu_mobile" class="VendorName\ModuleName\Block\Html\CacheMenu">
<arguments>
<argument name="custom_argument" xsi:type="string">topmenu_mobile</argument>
</arguments>
</referenceBlock>
</body>
</page>
Now, the MegaMenu is cached. The original time is only taken during the first page load; after that, the time is reduced as it comes from the cache instead of being processed for every page.
Conclusion
By implementing a custom cache type in Magento 2, we have significantly reduced page load times, enhanced the user experience, and simplified cache management through the admin panel. This straightforward yet effective technique plays a key role in optimizing Magento performance. If you need expert assistance, feel free to contact us today!
0 Comments