Why is my Magento 2 site slow?

As a hosting company we experience a lot of customers contacting us with regards to performance of their site. Furthermore a lot of frontend developers lack knowledge about this topic. This article will describe how to optimize performance on your Magento 2 installation. This subject will mainly describe how to improve your Magento 2's TTFB, so it's important you undertand the term.

Measure TTFB for your site

First of all we need to know what is going on. With magento 2 there is a lot of possible factors slowing down the site. So first of all we need to know the current TTFB. To do this open your browser (Firefox or Chrome) and open your developer tools and go to the network tab. In the address field type in the your sites url and press enter. Now you will see a lot of elements appearing in the developer tools. Go to the top and hover the waterfall item at your right side.

Now we know the TTFB and have a foundation for our debugging. If the Full Page Cache (FPC) is enabled and you run on minimum Shared Plus you would expect a TTFB between 100 and 250 ms on cache hits. With varnish enabled TTFB on cache hits should be between 20 and 60 ms.

If you have a higher TTFB than expected now its time to start debugging.

Magento 2 deploy mode.

Magento have 3 different deploy modes. If your site is live you should be running in production mode. To find the deploy mode of your magento 2 site you need to use ssh. Login to ssh on your Magentohotel or dedicated server and go to Magento's root folder (usually public_html). From there you need to run the following command: bin/magento deploy:mode:show

To enable production mode you should run bin/magento deploy:mode:set production. Make sure the command runs without any errors. If any errors occurs they need to be fixed before you can enable production mode. This is critical to achieve acceptable performance on Magento 2.

Magento caching

Developers tend to disable all caches when making changes to the site, which is understandable. However enabling all caches afterwards is also critical. Running Magento without some or all caches enabled noticably affects performance. To check if all caches are enabled run bin/magento cache:status. If any of the caches are disabled (0) run bin/magento cache:enable and then run bin/magento cache:flush to flush the cache.

Magento Full Page cache debugging

Enabling the FPC is not always enough to obtain an acceptable TTFB. If TTFB is still not below 500 ms the FPC is probably not working as expected. If this is the case you need to investigate the cause. The most common cause is some bad coded module or theme telling Magento not to cache the site. But first of all we need to know if all page views are cache MISS's. A MISS indicates that page requested was not found in the FPC, and therefore magento have to generate the page from scratch which takes longer time. If Magento succeeds to save a cached version of the site the next visitor of the specific page will get a cache HIT. If this is still a cache MISS the FPC is not working as expected.

To find out whether Magento always delivers cache MISS's you need to enable developer mode temporarily and flush the cache. Edit your .htaccess removing the # in front of SetEnv MAGE_MODE developer and flush the cache with bin/magento cache:flush. Now open your browser and go to the network tab in developer tools. Load your site in the browser. In the developer tools click the first entry in the elements-list and investigate the headers. Look for the header: x-magento-cache-debug. First page view after a cache:flush is expected to be a MISS. Reload the page and find the header again. If it is still a MISS the FPC is not working as expected on your site.

Now we need to find out if a module or a theme is configured to not use the cache properly. To do this we need to find a list of xml files containing the string cacheable=false. This is not necessarily a bad thing, actually it is necessary for Magento to be able to serve dynamic content eg. in the checkout. You would not want the checkout to be cached and therefore you can tell Magento to not cache certain blocks. However sometimes developers use this in a bad way, and the cacheable=false tag ends up in places they do not belong. Start by running this command in Magento's root folder: grep --recursive -l 'cacheable="false"' app/design/frontend app/code vendor. This will return a long list of primarily .xml files. We will be looking for the following file names:

  • default.xml is related to all pages in your site
  • catalog_cateogory_view.xml is related to the category pages of your site.
  • catalog_product_view.xml is related to the product pages.
  • cms_page_index.xml is related to the CMS pages.

If any of the files above is found in the list generated by the grep command you will need to fix it. You have to options:

  1. Contact the developer of the module or theme and tell them the case and ask them to fix the problem.
  2. Often times it is a matter of developers forgetting to remove the tag after debugging or developing. So often times you might just want to change cacheable=false to cacheable=true and flush the cache. When done flush the cache and check if everything is working as expected and check that you have cache HIT's.

If you are still exeriencing cache MISS's you need to debug further and check if there are still files containing cacheable=false that needs to be changed.

Magento 2 profiling

If your site is still slow even with cache HITS the next step for you is profiling. You need to know what part of the code that takes time. For this Magento 2 has an inbuilt profiler.

Furthermore you should check the following Magento 2 profiling projects:

https://github.com/clawrock/magento2-debug

https://github.com/vpietri/magento2-developer-quickdevbar