Accueil » Tous les articles » Magento 2 » Améliorer les performances de Magento avec les proxies

Améliorer les performances de Magento avec les proxies

Magento 2 a un certain nombre de mécanismes qui permettent d’améliorer drastiquement les performances et je vais vous parler aujourd’hui des proxies. Leur mise en place demande des connaissances de faibles à intermédiaires. Pour faire simple, cela revient à sortir les emportes-pièces du placard avant de faire la cuisine. Ils restent vides jusqu’à ce qu’on en ait besoin et si on ne veut pas en utiliser un au moment de la découpe, il n’y a pas à le laver mais avant de commencer à cuisiner, on ne savait pas si on allait l’utiliser ou pas.

Trouver les classes les plus importantes

Les commandes en console

Les classes où l’utilisation d’un proxy est la plus recommandée, pour ne pas dire indispensable, sont les commandes qui permettent d’ajouter des interactions avec le serveur directement en ligne de commande.

bin/magento list

Lorsque vous utilisez cette commande, toutes les injections de dépendances sont faites pour toutes les commandes du projet. Ce qui veut dire que si vous injecter dans une classe particulièrement lourde dans une de vos commandes de console, elle est injectée chaque fois que vous tapez une commande en utilisant bin/magento.

Les crons

Si vous utilisez des crons avec des injections de dépendances particulièrement lourdes et qu’ils sont exécutés toutes les minutes, cela peut conduire à une certaine lenteur qui pourrait être évitée facilement. De même, si pour votre import de produit, vous injectez des dépendances lourdes dans votre produit, il peut être bienvenu d’utiliser un proxy.

Les helpers

Les helpers devraient quasiment disparaître de Magento 2. Cependant, ils existent encore et parfois, ils étendent \Magento\Framework\App\Helper\AbstractHelper ou pire, \Magento\Catalog\Helper\Product\View qui injecte d’autres Helper qui n’utilisent que rarement les proxies. Les helpers ne respectent que rarement le SRP (Single Responsability Principle ou principe de responsabilité unique) et si leur redéfinition doit être le but, l’injection de proxies en lieu et place de classes lourdes est un bon début.

Les classes lourdes en général

Si vous savez que votre classe est lourde à charger, commencez par utiliser les proxies sur celle-ci puis injectez-là via un proxy dans celles qui en ont besoin.

Les cas où c’est inutile

Si la classe injectée est utilisée directement dans le constructeur ou dans une fonction automatiquement appelée quand la classe est instanciée, ce n’est pas la peine de mettre un proxy en place.

Comment procéder

    public function __construct(
        \Magento\Framework\App\Helper\Context $context,
        \Magento\Catalog\Model\Session $catalogSession,
        \Magento\Catalog\Model\Design $catalogDesign,
        \Magento\Catalog\Helper\Product $catalogProduct,
        \Magento\Framework\Registry $coreRegistry,
        \Magento\Framework\Message\ManagerInterface $messageManager,
        \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator,
        array $messageGroups = [],
        \Magento\Framework\Stdlib\StringUtils $string = null,
        ?LayoutUpdateManager $layoutUpdateManager = null
    ) {
        $this->_catalogSession = $catalogSession;
        $this->_catalogDesign = $catalogDesign;
        $this->_catalogProduct = $catalogProduct;
        $this->_coreRegistry = $coreRegistry;
        $this->messageGroups = $messageGroups;
        $this->messageManager = $messageManager;
        $this->categoryUrlPathGenerator = $categoryUrlPathGenerator;
        $this->string = $string ?: ObjectManager::getInstance()->get(\Magento\Framework\Stdlib\StringUtils::class);
        $this->layoutUpdateManager = $layoutUpdateManager
            ?? ObjectManager::getInstance()->get(LayoutUpdateManager::class);
        parent::__construct($context);
    }

Ceci est le constructeur de la classe \Magento\Catalog\Helper\Product\View. Dans ce cas, la session ($catalogSession) ou un helper de produit ($catalogProduct) sont injectés sans que cela n’aitvraiment d’utilité si le helper est utilisé pour la fonction : isDataForPriceIndexerWasChanged

    public function isDataForPriceIndexerWasChanged($data)
    {
        if ($data instanceof ModelProduct) {
            foreach ($this->_reindexPriceIndexerData['byDataResult'] as $param) {
                if ($data->getData($param)) {
                    return true;
                }
            }
            foreach ($this->_reindexPriceIndexerData['byDataChange'] as $param) {
                if ($data->dataHasChangedFor($param)) {
                    return true;
                }
            }
        } elseif (is_array($data)) {
            foreach ($this->_reindexPriceIndexerData['byDataChange'] as $param) {
                if (isset($data[$param])) {
                    return true;
                }
            }
        }
        return false;
    }

Aucun des deux n’est utilisé et pourtant, ils seront injectés quand même. Pour éviter cela, l’équipe de Magento aurait pu utiliser une notation dans etc/di.xml du module qui aurait ressemblé à cela.


    <type name="Magento\Catalog\Helper\Product\View">
        <arguments>
            <argument name="catalogSession" xsi:type="object">Magento\Catalog\Model\Session\Proxy</argument>
            <argument name="catalogProduct" xsi:type="object">Magento\Catalog\Helper\Product\Proxy</argument>
        </arguments>
    </type>

Ce n’est pas plus difficile que cela.

Besoin d’aide pour mettre cela en place ?


Publié

dans

, ,

par

Commentaires

Laisser un commentaire