Improve Slow Loading Magento 2 Large Configurable Products

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

.

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

Large Configurable Products are slow to Load!

One of the downsides to Magento 2 configurable products is that the large configurable products can become slow to load in the frontend when a lot of variations are configured. A configurable product with a lot of options can quickly become very LARGE. I worked on a store with a product that is available in over 250 colours and four sizes. This results in a configurable product with over a 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 Elgento open sourced a module they had developed for a customer experiencing exactly this problem with slow loading large Magento 2 configurable products. 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 json variation data.

When I found 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 the module to make it compatible and also added AQMP/RabbitMQ integration and am now using it in product without any issues.

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 host, 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 now load variation data via an ajax request. If a product has not been prewarmed by an index upon first frontend load the variation data will be created and cached. You can also manually create the variation data using a console command

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

This will force a prewarm of variation data for a configurable product with the id 1234.

When you make a change to a configurable product, or a child of a simple product the module uses a message queue to update the configurable product cached data. Magento 2 has built in AQMP/RabbitMQ integration and you can configure this using the following env.php configuration :

 

'queue' =>
  array (
    'amqp' =>
    array (
      'host' => 'magento2_rabbitmq_1',
      'port' => 5672,
      'user' => 'guest',
      'password' => 'guest',
      'virtualhost' => '/'
     ),
  ),


Messages are created by a publisher and actioned by a consumer. 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 variation 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 build 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 are 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

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