Advertisement

Facebook

Magento 2 Custom Cache Type for Improving Page Load Time

Magento 2 Custom Cache Type for Improving Page Load Time

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!

Post a Comment

0 Comments

Buy Me A Coffee