As an introduction, I want to say don’t be fooled.
I’m sure this is not the first article about Magento 2 optimization that you’ve seen. There are tons of them on the web and most of them are giving you false expectations. First of all, do not trust articles that advertise 99/100 performance scores. What scores do they advertise, tetris? You can’t put all the job you need to do to get highest google scores in a single article. And you won’t be able to do this without a tech knowledge.
Second, do not run for scores. You shouldn’t blindly try to get the highest score possible. Speed tests are made to help you, to point you on the possible weak spots of your site. But they are not always accurate and can be absurd. For example it can suggest you to combine images in sprite when you have HTTP/2 enabled, this is meaningless unless you have hundreds of tiny images. Your aim should be to make it fast and easy to browse your website for your customers.
Below we will describe some basic steps, it’s more like an optional checklist that can help to make your Magento 2 store work faster but to make it lightning fast you will need to hire a professional with specific expertise. And again do not use these recommendations blindly. Make tests and find out what works best for your setup.
Optimization check list
- Follow Magento 2 best practices and recommendations
- Choose fast hosting
- Enable Magento cache
- Make sure Production Mode is on
- Disable Flat Catalog
- Disable JS bundling
- Enable CSS/JS minification
- Merge CSS and JS Files
- Use Varnish or other cache
- Enable Redis cache
- Image Optimization
- Enable gzip compression
- Nginx + FPM
- Use the latest PHP version possible
- Enable HTTP/2
- Defer parsing of JS
- Lazy load images
- Test/Audit and Disable Extensions
- Database optimization
Additional/Optional optimization
- Clean Up Database & Logs
- Content Delivery Network
- Search with Elasticsearch
- Disable “all products” in catalog view
- Disable Shipping Methods You Don’t Use
Choose fast hosting
Skip shared hosting. You should choose fast hosting but definitely not the best and most expensive hosting plan possible, as people usually suggest. You don’t need a truck to drive your kids to school. Choose hosting plan exactly for your needs. Check Magento 2 hardware recommendation.
Choosing the right hosting for your Magento 2 store deserves its own article but if you just launched a new store with a few hundreds of products then you can use one of the main advantages of VPS, its rapid scalability. Simply choose VPS that meets Magento 2 minimum requirements (with some margin) and easily upgrade (usually in one click) it in future, once needed. Choose managed VPS if you are not a tech person.
Enable Magento Cache
Always keep cache enabled and simply clear it when necessary. Disabling cache is a bad idea, even for development. System > Cache Management
Make sure Production Mode is on
This probably should be your first step in Magento 2 speed optimization. It is very important to enable production mode on your live store. Production mode has better performance because static view files are populated in the pub/static
directory and because of code compilation. You can lean how to enable production mode on Magento official documentation.
Check what is your current mode using this command:
bin/magento deploy:mode:show
Enable production mode:
bin/magento deploy:mode:set production
Disable Flat Catalog
Magento officially do not recommend to use Flat catalog starting version 2.3.0:
Starting with Magento 2.3.0+, the use of a flat catalog is no longer a best practice and is not recommended. Continued use of this feature is known to cause performance degradation and other indexing issues.
Disable JS bundling
This feature is very questionable and has no advantage if HTTP/2 is enabled and we strongly recommend to enable HTTP/2. It is even mentioned in Magento 2 configuration best practices:
Activating the HTTP2 protocol can be a good alternative to using JS bundling. The protocol provides pretty much the same benefits.
You can learn where to disable js bundling below.
Merge and Minify CSS and JS Files
Following options are only available in Developer Mode.
Navigate to Stores > Configuration > Advanced > Developer
Under JavaScript Settings set
- Merge JavaScript Files – Yes
- Enable JavaScript Bundling – No
- Minify JavaScript Files – Yes
- Move JS code to the bottom of the page – Yes
Move JS code to the bottom of the page option available in Magento starting version 2.3.2.
Under CSS Settings set
- Merge CSS Files – Yes
- Minify CSS Files – Yes
Use Varnish cache
Some people recommend using built-in cache instead of Varnish and provide following arguments: Not so easy with SSL traffic, Additional point of failure, etc.
This is bullshit. Varnish can give your Magento 2 website 10x boost in load speed. There is nothing complicated to make it work with ssl, we’ve described it in this article: Speed Up Magento 2 with Varnish and Nginx as SSL Termination on Ubuntu. Without all the basics and ssl setup this article would be in a few lines: 1. Install varnish 2. Copy config from magento 3. Copy config to nginx. That’s all. By following our instructions you will get the same Varnish Architecture as recommended by Magento: https://devdocs.magento.com/guides/v2.3/performance-best-practices/reference-architecture.html
Another point of failure? Every single extension you use with Magento is a point of failure, so will you use naked Magento? I bet no. Such statements are ridiculous. Do not use a car or any transport to get to another city because you can get in crash. Go on foot!
Enable Redis cache
You can use Redis cache for session storage in addition to Varnish full page cache. It is pretty easy to enable in Magento 2, you can even do this with command line. Check detailed instruction on Magento official docs: Use Redis for session storage.
Image Optimization
You can optimize image create your website content, before uploading them to Magento. This can be done using Photoshop save for web feature or various tools and services, like following:
- Akamai Image Manager
- imgix
- Image Engine
- Cloudinary
- Uploadcare
- ShortPixel
- Kraken.io
- TinyPNG
- Imagify
- ImageOptim
Or you can optimize images on server side. This can be done with small command line tools like jpegoptim
and optinpng
for jpg and png images accordingly. Or using powerful Page Speed Mod https://www.modpagespeed.com/
Use following commands to install jpegoptim
and optinpng
apt install jpegoptim apt install optipng
Now you can use following syntax to optimize individual images. Replace <filename> with actual name of the file to be compressed, and choose the proper extension:
jpegoptim <filename>.jpg
To optimize all png images use this command:
find ./ -type f -iname "*.png" -exec optipng -strip all -o4 {} \;
For jpeg:
find ./ -type f -iname "*.jpg" -exec jpegoptim --strip-all --all-progressive -pm85 {} \; -exec chmod 644 {} \;
For details about jpegoptim and optipng run man jpegoptim
and man optipng
accordingly.
Enable gzip compression
If you use default Magento 2 config for nginx then it is already enabled. Just make sure that gzip
directive included in your nginx config with parameter on
. You can easily check if it works in chrome browser inspector. Right click in chrome browser and choose inspect. Switch to network tab and reload the page. Now check the content encoding column to see what content is compressed and which is not.
Enable gzip compression in nginx.
Enable HTTP/2
Why is it important? HTTP/2 can send multiple requests for data in parallel over a single TCP connection. This is the most advanced feature of the HTTP/2 protocol because it allows you to download web files asynchronously from one server. Most modern browsers limit TCP connections to one server. This reduces additional round trip time (RTT), making your website load faster without any optimization, and makes domain sharding unnecessary. For more details check this article: HTTP/2: the difference between HTTP/1.1, benefits and how to use it
How to enable HTTP/2 on nginx? Its pretty easy simply add http2
to listen directive in your server block:
listen 443 ssl http2;
We have described how to configure nginx server block with ssl and http2 in our article about varnish on nginx with ssl termination.
Defer parsing of JS
Defer parsing of JavaScript helps improve initial page load time by moving JavaScript to the bottom of the page. How? Various plugins and themes add lost of scripts to website. Browser load content from top to bottom and if it finds JavaScript along the way, the browser will stop and fetch it (if it’s an external file), then parse it and only after that it will continue to load the rest of website. This is critical when you use lots of plugins and a heavy theme. And you probably do. But no worries. We have made a free extension for Magento 2 to help you with this: Magento 2 Defer Parsing of JavaScript Extension
Lazy load images
Load images on demand, instead of loading all of them at the initial page load. This can greatly increase website load speed because images are loaded only when they are visible on the page. So without lazy load it’s possible you’re loading stuff the user may never see. You can check it in action on our Athlete 2 Magento 2 Theme. You can’t easily enable lazy load it should be incorporated in theme. But if your theme missing this feature you can try some of the free extension available on the web.
Test/Audit and Disable Extensions
Test 3rd party extensions for performance and disable unused.
If you are a tech person you can run Magento built-in profiler and MGT Developer Toolbar to analyzing performance. If not, you can use primitive method: enable/disable extensions one by one. It is a good idea to do this if you see performance issues after you have installed 3rd party extensions. Try to disable them one by one to determine which of them are causing issues.
Disable unused Extensions
Disable or completely remove unnecessary extensions from your store.
You can learn how to disable extensions from Magento official docs.
Run bin/magento module:status
to see the list of enabled and disabled modules and their correct names.
Then run bin/magento module:disable Vendor_Module
and change Vendor_Module
to the name of the module you want to disable. Ie.:
bin/magento module:disable Olegnax_MegaMenu
You can enable it back the same way:
bin/magento module:enable Olegnax_MegaMenu
Database optimization
If you are managing your own server you may need to tune MySQL. You can run this handy mysqltuner script to get performance suggestions. MySQLTuner is a script written in Perl that allows you to review a MySQL installation quickly and make adjustments to increase performance and stability.