Table of Contents
- 1 Introduction
- 2 Testing Environment
- 3 Chapter 1. Magento Setup and Server Configuration
- 4 Chapter 2. Additional Tools
- 5 Instead of Final Words
According to Statista, the number of mobile phone users in the world is expected to pass the five billion mark in 2019. With that regard, Google places the utmost importance on site loading speed on mobile devices. This parameter undoubtedly influences the search results ranking. Additionally, fast website load time increases conversion as sites get to avoid losing inpatient users.
In the first part of this article, we will try to figure out and showcase whether it is possible to speed up Magento 2 page load time using standard means or not and, most importantly, define how effective these means are.
In the second part, we will provide an insight into the effectiveness of 3rd party solutions and approaches.
All the measurements will be made in Chrome Audit with ‘For mobile device with simulation Fast 3G’ limitation:
Magento 2.3.1 unfolded in the Docker container will be used in the review. This will allow us to isolate resources.
We will measure performance in the production mode with fully enabled built-in cache.
Testing will be carried out on three site pages: main, product and category ones. For each this page, we will run audit checks three times. An average test result will be selected.
As we won’t run load-testing ― while pages load time on the client side in a browser will be primarily covered in this article ― MySQL and PHP versions will not be specified. Not the result in its absolute terms but the difference in performance between various configurations will be of primary interest for us.
How is it possible to speed up page load time using standard Magento and server means?
Above all, this can be achieved by reducing either the size of sent data or the number of requests. Read on for more detailed insights.
Chapter 1. Magento Setup and Server Configuration
As it can be seen from the table below, the first and most critical thing to do ― you are right, it has no relevance to Magento setup ― is to enable compression on the server. Data volume is the key factor that determines loading speed in slow mobile networks. With compression being enabled, a site gets depicted much faster. The inevitable drawback includes an increase in the First CPU Idle parameter as the result of unpacking on the server-side.
With Gzip enabled:
Minify Js and CSS
What if we try to reduce the size of the transmitted data even more? In the first place, let’s enable Minify Js and Minify CSS. Then, make a comparison.
All the optimization-related configurations can be found in Stores -> Configuration -> Developer:
The tab is solely available in the developer mode. While in production mode, make sure to switch to the developer mode first, using the following command:
> bin/magento deploy:mode:set developer
Then, you’ll be able to see the Developer section, make the necessary configuration changes, clear cache and switch back to the production mode once again:
> bin/magento deploy:mode:set production
Upon that, static-content deploy takes place.
The suffix min gets added to js/css files:
Data volume has decreased indeed! For the home page, 1 Mb instead of 1.3 Mb was transferred.
If you think this has improved our parameters by one third, you are wrong. The situation has got better, but not significantly.
We ran it again and again, but the results were stable, i.e., despite the fact that there were certain improvements, they were not in proportion to the decrease in the transmitted data volume.
Merge Js and Merge CSS
Now, it’d be logical to assume that further improvements must be related to the decrease in the number of requests rather than to data volumes.
Let’s give it a try and enable Merge Js and Merge CSS configurations.
Note that Magento itself describes this feature as an outdated one:
‘We do not recommend using deprecated settings like merging JS and CSS files, as they were designed only for synchronously-loaded JS in the HEAD section of the page. Using this technique can cause bundling and requireJS logic to work incorrectly.’
Nevertheless, let’s give it a go:
The changes in the number of requests are not impressive, are they?
Though such parameters as ‘First Contentful Paint’ and ‘First Meaningful Paint’ have been bettered, there is certainly room for improvements.
Let’s give a try to the JS Bundle technology, where js files get bundled based on a fixed size. This allows us to manage the number of requests while an overall data volume remains unchanged.
The results are underwhelming. The thing is that the built-in Magento mechanism collects js-bundles for all site, i.e., practically all js will be collected all the way through on any page. This will lead to a sharp increase in page volume.
Yes, you can exclude certain js files from bundles (some of them are excluded by default). However, you do not get to do that for a specific page.
Magento also does not recommend to enable Bundle JS in the production mode. Seems like it’s a second option that is available, but factually ― not really.
Advanced JS Bundle
Magento recognizes difficulties with Bundles JS but offers to avoid addressing them on your own. In the official guide, you’ll find an example on how it is possible to bundle only the required js-files on a current page. Yes, this is a little more difficult than changing a parameter in the config. For Advanced Bundle, you’ll have to use Nodejs, Require JS, Phantom JS. Of course, this is not a ready-made solution. But after testing the offered mechanism, we will have an idea about how Advanced Bundle can speed up the page load time, from the theoretical perspective.
The suggested mechanism works in manual mode and not inside but outside the framework. The special tools analyze js-files that are loaded on pages and collect them in a bundle, either a general one or a specific for the page TYPE bundle.
Ultimately, the collected bundles get written in require js and loaded by it on a page:
On each page type (naturally, for which a bundle was collected), a specific bundle gets loaded. This would be an example for home page:
It would seem that after we’ve reduced the number of requests, extra data does not get loaded and performance must significantly increase… But the critical for SEO First Contentful Paint and First Meaningful Paint time have dramatically increased as well. That makes sense. Until the bundle file gets loaded, no tracking will take place.
Seems like we’ve tried our utmost, or not? I guess it’s high time to move on and try current technologies.
Let’s disable Bundle JS in Magento and enable HTTP/2 on the server.
In our case, it’s just nginx. What we have done is changed a few lines ― added http2 support for 443 port.
listen 443 ssl http2;
For testing in Chrome, we will need to add the self-signed certificate to the Trusted Root Authority (MacOS in our case).
Here’s how the HTTP/2 connection looks like:
This has improved all the parameters without any exception! It’s all down to the features of the HTTP/2 technology.
Decrease in access delays to speed up page load time, in particular by:
- data compression in HTTP headers,
- usage of puch-technologies on the server side,
- requests conveyerization,
- resolution of head-of-line HTTP 1.0/1.1 protocols blocking,
- multiplexing numerous requests in one TCP connection.
With HTTP/2, a large number of requests won’t be a problem as no TCP connection opens for each request.
HTTP/2 is supported by up-to-date versions of nginx and apache in the majority of actual browsers: https://caniuse.com/#search=http2
With that regard, you may have the following question: What if we combine Advanced JS Bundle and HTTP/2?
Theoretically, it won’t speed up page load time as HTTP/2 does not have significant advantages in loading large bundle js files. But to know it for sure, let’s check it.
As we see, using Advanced Bundle JS within HTTP/2 connection does not improve speed.
An attempt to fine-tune the bundles is a time-consuming process. It requires bundles to be re-generated after each Magento or a 3rd party extension (that adds JS on the front-end) update, as well as after adding new product types that connect their specific js or that do not use js of other product types. Basically, there are more nuances to consider. In my opinion, moving towards Bundle JS won’t yield significant results if you have a possibility to use HTTP/2.
What other means of speed optimization exist? Is it possible to make page load time even faster?
Honestly, we planned to review this optimization means from 3rd party vendors, but while this article was in the process of creation, Magento 2.3.2 got released. This feature has got added to the new version (and disabled by default).
When enabled, some js-files get transferred from the <head> section to the end of </body>, which should speed up the beginning of site’s visualization in theory.
That’s what we had in the beginning:
Here’s what we’ve got after having it enabled:
To run such testing, we had to update our Magento version to 2.3. The quantity and size of connected files were changed. Therefore, test results can be rough. To understand how Magento version itself has influenced the results, we compared M2.3.1 vs M2.3.2 versions with HTTP/2 + Minify JS/CSS combination first ― and the obtained results were practically equal, which do not surpass the uncertainty of measurement.
Within all the overviewed means of Magento speed optimization, the following variants seems to be in the lead:
Gzip + Minify JS/CSS + HTTP/2 + Move JS code to the bottom of the page
Let’s consider it as a starting point and move further. Previously, we played around with configurations that touch upon JS/CSS solely. Thus, there are certainly aspects that can be improved.
The setup can be found here:
HTML part of the home page ― 89 Kb before and 88,7 after HTML Minify / with compression on the server ― 12,2 against 12,1 Kb.
HTML part of the category page ― 155 Kb before and 100 after HTML Minify / with compression on the server ― 16,8 against 15,2 Kb.
HTML part of the product page ― 80 Kb before and 67 after HTML Minify / with compression on the server ― 15 against 14,1 Kb.
As compression on the server side is used, 1-2 Kb difference is not critical and is within the audit drawbacks.
Chapter 2. Additional Tools
Third-party extensions: Minify/Merge JS/CSS/HTML | Bundle JS
In the meanwhile, there is not much point in going for 3rd-party solutions for JS/CSS/HTML and bundle JS. Even if you get to achieve extra compression results, they will be limited to a share of one percent on the front-end. In return, you’ll get one or several more Magento extensions in the system. The fact of their presence and operation of their algorithms requires additional resources, as well as increases the risk of system failure in general. If you are not sure that the potential benefit outweighs the related risks, it is recommended to withdraw from their usage.
If you know any 3rd party solution that drastically improves loading speed through compression and bundling, we encourage you to share it in the comments or inform us directly at firstname.lastname@example.org. We will be happy to investigate it 😉
Now, let’s try to make improvements using means that are not available in Magento by default.
Decrease image size
Usage of images on the web is always a compromise between quality and image file size.
Our main concern is the reduction of image size without quality losses. Well, using default Magento functionality, it is possible to decrease image size indeed. But the quality of images will suffer significantly.
Let’s decrease the size of standard images, which Magento converted and resized based on the configurations, i.e., we are mostly interested in images that are located in magento_root_directory/pub/media/catalog/product/cache.
Magento configurations can be found here:
As a start, let’s try to do it manually and use the jpegoptim utility. Multiple modules that are aimed at speeding up Magento (including the paid ones) are powered by this utility.
No results for images from cache unless we decrease image quality:
There seems to be something wrong about that. For testing purposes, we applied it to the original image, which is not displayed on the page in fact. We did manage to achieve certain results, though insignificant ones:
What about going for automated solutions?
Let’s try the following free image optimizer: https://github.com/justbetter/magento2-image-optimizer.
We’ve installed all the offered utilities that are used by the extension:
The image compression settings have been set up to 80 for JPEG. This corresponds to the default Magento settings. Then, we ran optimization for all media directory.
Full media directory size before compression is 353 Mb, after ― 340,1 Mb
media/catalog/product/cache directory size is 194,7 Mb and has not changed after compression.
We’ve found the solutions convenient and useful, especially if you do not get the images ready before uploading them to your site.
However, when it comes to decreasing the overall image size on product and category pages, no significant improvements have been achieved.
Probably, other image formats are mainly used in your case. Thus, the results might be even more significant.
We intentionally don’t overview webp image format here as apple browsers do not support this format: https://caniuse.com/#feat=webp.
Alright, if we can’t significantly decrease image file size, let’s try to upload them only for the visible area.
Lazy Loading Image
Let’s try the first FREE 3rd party solution we come across ― Magento 2 Lazy Loading.
As previously, we ran audit on product, category and home pages.
No significant changes have been achieved. The variations are within the uncertainty of measurement.
This is probably because the sample data pages are quite lightweight and all primary images are located right in the visible area.
Products description does not contain images. The category does not have a description at all.
Let’s do it the easiest way and simply increase the number of products (including the number of loading images) on the category page in pager ― first from 9 to 30, then up to 48 and list the results.
The results are evident. The larger (in quantity and size) are your images in the invisible at initial load website area, the more significant are the advantages. The feature is surely a useful one from the optimization standpoint though it does have certain usability disadvantages.
Instead of Final Words
We’ve overviewed both standard Magento features and some 3rd-party solutions that allow optimizing page load performance.
Despite the research, we find it difficult to draw firm conclusions as all websites are unique and have their own one-of-a-kind peculiarities. Thus, there is always some level of probability that solutions that work for one site won’t have any effect for other ones.
However, the most useful features that have a meaningful effect is the default Magento’s Gzip + Minify JS/CSS + HTTP/2 + Image Lazy Loading
About Bundle JS
Thus, advanced versions of this bundle from 3rd party extension developers will hardly allow significantly increase load speed without additional personalized site fine-tuning.
There are surely more means to try that can help increase load time. However, many of them are not one-size-fits-all solutions. For example, correlation of site visitors from different countries across the world and the physical server/servers location also matter. It makers sense to transfer the site to a server, from which data transfer will be faster for the majority of site users/use CDN for static files. If site visitors are primarily from one region, then you may try to cache static files using Varnish: https://devdocs.magento.com/guides/v2.3/config-guide/varnish/config-varnish-magento.html#cache-static-files.
Ultimately, a means that essentially changes the situation and makes your site maximally fast on mobile devices is using the AMP technology.
For handheld devices, from Google SERP, a user will get not to your site but to its cached version that is stored on Google servers. The initial load will be as quick as lightning. Such websites get naturally indicated with a lightning in the SERP.
This technology is not a simplistic one and assumes using only own amp js-libraries. Additionally, you get a chance to have a separate pages’ version that is not connected to your current theme in any way.
This can be a tough choice to make. On the one hand, it’s all about improved load speed and conversions. On the other one, it’s limitations that the AMP technology imposes, i.e., you get to use js and HTML only from AMP libraries. As a result, the functionality gets limited.