Improve Slow Loading Magento 2 Large Configurable Products

created June 29, 2020, last updated August 20, 2020.

.
closeThis post was last updated 3 years 8 months 23 days ago, some of the information contained here may no longer be actual and any referenced software versions may have been updated!

Configurable products have changed a lot in Magento 2.

Compared to Magento 1, Magento 2 configurable products are just containers for simple products (variations). You can no longer configure pricing data directly in the configurable product as the parent configurable inherits all it’s unit, tier price and inventory data from the child simple products. It’s also much easier to create products with variations such as size, colour etc. and display them in the frontend in various different ways i.e. visual swatches.

Large Configurable Products are slow to Load!

One of the downsides to Magento 2 configurable products is that large configurable products can be slow to load in the frontend if a lot of variations are configured. I worked on a store with a product that is available in over 250 colours and four sizes. This resulted in a configurable product with over 1000 child products and whilst theoretically there is no limit to the amount of simple products in a configurable container product in practice, the way Magento 2 builds the frontend product can lead to very slow load times.

In the frontend, Magento 2 loads all variations in a giant JSON object and renders that into the DOM. This JSON object is 20 megabytes for 10,000 variations. In the backend, this JSON is also built and passed to a UI component wrapped in XML. PHP’s xmllib is not able to append extremely large XML structures to an existing XML structure.

Even with 1000 variations page load time for an uncached configurable product was in excess of 30 seconds.

Elgentos LCP

Fortunately the nice people at Elgentos open sourced a module developed for a customer experiencing exactly this slow loading Magento 2 configurable product problem. elgentos/LargeConfigProducts greatly improves the loading time of large configurable products by pre-caching the product variation data in the backend and loading the frontend variation JSON as an asynchronous ajax request. This results in a much faster load time of the parent product and the cached variation data.

When I tested the module there were some issues with Magento 2.3.x compatibility which the developer had not had time to correct. I made some changes to make it compatible and also added AQMP/RabbitMQ integration. I am using the module in production without any issues and it has made a big difference to page loading times.

Here are a few notes on installing and using the module with Magento 2.3.x.

After installing elgentos/LargeConfigProducts you should configure the prewarm settings

Elgentos LCP Prewarm Settings
Elgentos LCP Prewarm Settings

“Prewarming” is the process of creating and caching the variation data for configurable products. The module uses Redis to cache the data and you should specify your Redis hostname/IP, TCP port and choose a new database for the data.

The module includes a new indexer that will prewarm all configurable products when you manually reindex with bin/magento index:reindex

With the module configured and enabled all configurable products will now load variation data via an Ajax request. If variation product data has not been prewarmed or cached the cache will be updated when the product loads. You can also manually create the product variation data cache using a console command

bin/magento lcp:prewarm --products 1234,12345 -force

This will force a prewarm of variation data for a configurable product with the ids 1234 and 12345.

When you make a change to a configurable product, or a child of a configurable product the module uses a message queue to update the configurable product cached data. Magento 2.3 has built in AQMP/RabbitMQ integration and you can add a Rabbit MQ server to your Magento 2 system by using the following env.php configuration :


'queue' => [
'amqp' => [
'host' => 'RABBITMQ_HOST_NAME',
'port' => 5672,
'user' => 'guest',
'password' => 'guest',
'virtualhost' => '/'
] ],

Messages are created by a publisher and actioned by a consumer process in the module. To list all the configured Magento 2 consumer queues use:

bin/magento queue:consumers:list

You will see that elgentos_magento_lcp_product_prewarm is listed. To run the prewarm consumer use bin/magento queue:consumers:start elgentos_magento_lcp_product_prewarm this will start processing all messages generated by the module and updating the product variation data cache for any products that have been changed.

You should ensure that your consumer process is always running. If you use Docker you can create a small consumer container for this purpose.

    consumer1:
        hostname: shop01_consumer
        build:
            context: ./consumer/
        volumes:
            - "${CONTAINERDATA}/${PROJECT_NAME}/www1/dev/magento2:/var/www/dev/magento2"
        depends_on:
            - mysql
            - rabbitmq
        restart: always
        entrypoint: ["php", "./bin/magento", "queue:consumers:start", "elgentos_magento_lcp_product_prewarm"]

I can also recommend using the RabbitMQ Docker container image: rabbitmq:management the built in management gui is useful for monitoring message data here you can see the lcp message generation for the prewarm consumer after performing a reindex

RabbitMQ Management Gui
RabbitMQ Management Gui

In my opinion this functionality should be built into Magento by default to improve the loading time of large configurable products. Changes might be coming to configurable products in Magento 2.4 so perhaps there will be improvements made in this area.

Many thanks to Elgentos and Peter Jaap Blaakmeer for making this module freely available to the community and allowing me to contribute to it.

Comments

  1. Kim Domino Evers says:

    Hi there

    Thanks for the tip – the code you are mention to the env.php file just gives me a blank screen. In mine Magento it’s bracket like []

    ‘queue’ =>
    array [
    ‘amqp’ =>
    array (
    ‘host’ => ‘localhost’,
    ‘port’ => 5672,
    ‘user’ => ‘USERNAME’,
    ‘password’ => ‘PASSWORD’,
    ‘virtualhost’ => ‘/’
    ),
    ],

    • PAJ says:

      Hello, I am not aware of any issues with the module. What version of Magento are you using? Check bin/magento module:status to confirm the module is installed. Find the id of a configurable product and goto YOURSHOPURL/lcp/fetch/productOptions?productId=CONFIGPRODUCTID the module controller should return the child product options in json format. Check your logs for errors in case there is some other problem with your shop and the module.

This site uses Akismet to reduce spam. Learn how your comment data is processed.