From time to time we receive complaints from our customers for the slow speed of their Magento 2 stores.
They ask us to help them to solve the performance problem and speed up Magento 2 store.
In this article, we tried to collect our experience and share a few hacks regarding fixing the Magento store cache system.
It’s a very rare occasion that a Magento 2 is slow because of a weak server. In most cases, speed issues are related to the poor quality of some extensions or custom code inside your store. So to solve the problem and fix it, you need to spot the root causes.
Let’s start with some basic info on the cache workflow and it will greatly help us later.
What is Full Page Cache and why is it so important?
According to Wikipedia, the cache is a component that stores data, so future requests for that data can be served faster.
In Magento 2, a full-page cache module stores the entire HTML code of a generated page in the cache storage. As storage, Magento may use either a simple file system or more sophisticated systems (like Redis).
When your store visitor opens any store page in the browser, his or her request goes to the Magento 2 cache system. If the requested page is inside a cache storage, it is quickly returned to the visitor. A speed of such an operation is very high. If the requested page is not present in the cache storage yet, Magento generates this page, adds it to the cache storage and returns to a customer. The speed of such an operation is much slower.
We see that if a page is served from the cache, Magento sends a response very fast. If a page is not in the cache - the response is slow.
The correct work of the cache system directly affects the store speed. And, as you know, the speed influences the store performance in Google search results and conversion of store visitors into buyers. So the importance of the cache system is huge and Magento 2 speed optimization is a very important task.
Cacheable or Uncacheable
At first glance we realize, the more pages are inside the cache, the faster the store is.
Unfortunately, in many cases, this scenario is not possible: a store receives changes of products, categories, prices constantly, and Magento needs to clear outdated pages from the cache to display these changes correctly in the store frontend.
Additionally, not all the pages can be added to the cache. Some pages are defined as ‘uncacheable’, meaning that Magento must generate these pages with every single request.
Even more, some blocks may be defined as ‘uncacheable’. It means that every page with such a block inside requires to be generated from scratch by Magento with each request from a visitor.
There is a list of default pages which are cacheable:
- Home page
- Category page
- Products list page
- Product page
- CMS page
And there is a list of pages defined as uncacheable:
- Cart page
- Checkout page
- All pages of customer account
Why is this page loading so slow?
When any customer tells us that he or she has a slow store, the first thing we do is: we look for the slow pages. When they are determined, it helps us to find the core source of the problem. We will ask you to find such pages in your store and exam them individually using the following steps:
1. Check that Full page cache is enabled
First of all, please, open your Magento admin panel, go to the System > Cache Management and check if the Full page cache is enabled.
It may sound funny, but we saw a lot of times, when developers did some job on a store, disabled the cache and forgot to enable it back at some point. As a result, the store was working without any cache and slowly.
2. Check if a page is served from the cache
There are two simple ways to check if a page is served from cache or not. You may use the one you consider to be simpler.
a) Check by the response time For instance, you have a page http://store.com/page1.html Open it in your browser. Then, open browser development tools: it will show you the page generation time.
Add any GET parameter to the end of the URL and open the new URL (e.g. http://store.com/page1.html?random). Write down the page loading time from the developer toolbar, you will need the time for the following comparison. In this case, the page is generated from scratch, so its loading time is high.
Then, open the initial page http://store.com/page1.html and, again, write down the loading time from the developer toolbar. Now the page should be served from the cache, i.e. its loading time should be much smaller than in the previous case. If it is not - the page is not served from cache and that’s a problem.
b) Check by Magento headers To use this approach, you need to switch your Magento store to dev mode. Probably, it is not possible if your store is in production mode and has heavy traffic. But if you do tests on your dev host, this approach should be fine for you.
To switch your store to dev mode, just run the following command via SSH:
bin/magento deploy:mode:set developer
Then open any page and in developer tools of your browser check the headers of that page (for Chrome you need to open View / Developer / Developers Tools and tab Network).
Find the header X-Magento-Cache-Debug. If its value is MISS, then the page is not served from the cache. If its value is HIT, then the page is from the cache and should be loaded fast.
c) Check using toolbar of Mirasvit Full Page Cache Warmer extension Probably, it’s the easiest way to check the current issue and spot similar issues in the future.
Just enable the toolbar in the Store / Configuration / Page Cache Warmer. Open any page and you will see the cache status. Also, you will see the information regarding uncacheable blocks.
After doing the above checks, you definitely will be able to answer the question is your cache works fine for the target page or not. And if you found that the cache is not working, then it’s time to fix it.
I know, that it’s the cache problem. How to fix it?
There are different types of cache problems that may happen. Some problems are pretty easy, hence others need a careful approach and developer debugging.
However, from our experience, in 90% of cases, a page is not added to the cache (and cache is not working for that page), because of uncacheable blocks presence somewhere inside the page. If all your pages are not added to the cache, then you have uncacheable blocks globally defined, and they disable your full page cache system entirely.
To fix this cache problem, you need to find incorrect uncacheable blocks and remove or fix them.
All blocks are defined in the layout files, which are placed in the following folders:
There are a lot of files inside those folders. It’s very time consuming to check each file manually to find the issue. So we created a set of commands that will greatly speed up the process.
You can search uncacheable blocks using the following SSH commands:
cd app/design/frontend/ && grep --recursive -l 'cacheable="false"' * && cd ../../..; cd app/code && grep --recursive -l 'cacheable="false"' * && cd ../..; cd vendor && grep --recursive -l 'cacheable="false"' * && cd ..;
You can also get the list of uncacheable blocks from the toolbar of our Full page cache warmer extension:
At this point, we got the list of uncacheable blocks, let’s spot incorrect ones. We need to check only blocks which are inside the following files:
- default.xml is responsible for all pages of your store
- catalog_product_view.xml is responsible for product pages of your store
- catalog_cateogory_view.xml is responsible for the list of product pages of your store
- cms_page_index.xml is responsible for CMS pages of your store
If you see any uncacheable blocks inside these files, then you have found the source of the issue. Now it’s time to fix it. You have two options:
a) Make block cacheable by changing cachable=”false” to cachable=”true” . It may work or not for your case, depending on the block purpose. After doing such changes don’t forget to flush the cache.
b) Contact developers of the extension that creates that block and ask them to fix the problem. As a temporary solution, you may disable the extension if it negatively affects your store speed.
After fixing issues with uncached blocks, your cache should start working much better. On the FPC toolbar, you should see the high level of cache hit rate, which means that most of your pages are served from the cache.
Magento 2 Page Cache greatly improves the speed of the store. Your store should be correctly developed and use ‘cache-friendly’ extensions to use all the potential of the Magento cache system.
From our experience, in most cases, page cache is not working because of the presence of globally defined uncached blocks. To spot and fix such blocks, you can follow this post tips. As a result, after solving the issues with your Full page cache you will see a great improvement in the speed of your store.
Don’t forget that the store speed may affect your Google search results and, thus boost the number of visitors and buyers.