Skip to content

Performance Optimization

Backend vs. Frontend Optimization

Performance optimizations can be divided into two parts: backend optimization and frontend optimization.

Both are very important.

Backend optimization includes things like server resources, service settings like properly configuring the PHP opcode cache, using a reverse caching proxy like Varnish, Fastly, or others, optimizing SQL queries, and ensuring data is not loaded in a loop.

The backend optimization is important when a visitor requests an uncached page.
Once a page is cached in Varnish, the backend optimization no longer plays a role, since browser requests no longer even reach Magento. Instead, Varnish sends the response directly to the client.
A response from the Varnish cache is a lot quicker than a response for an uncached page. Times around 200ms for the time to first byte are common.

While slow backend performance does impact Core Web Vitals and Google Lighthouse results for uncached pages, once a page is cached, only frontend optimization can influence the scores.

If a cached page is delivered within 200ms and still has a Google Lighthouse score below 100, all the missing points are due to frontend factors, many of which often can be optimized with little effort.

Frontend optimization has many areas, just like backend optimization.

It includes things like resolution and compression of images, page layout stability, main thread blocking time, UI responsiveness and interactivity, accessibility, index-ability, and more.

Years ago, performance optimization was all about the backend. The ways to optimize backend performance are more widely known and mature compared to frontend optimization, which is an area that is still rapidly evolving.

When improving metrics like Google Lighthouse scores or when trying to pass Core Web Vitals, only focusing on one side is not enough.
As a Magento theme, Hyvä touches on both the backend and the frontend, however, the frontend is certainly where most of the focus lies.

Tooling

There are many tools to help developers with frontend optimization. Starting it can be a bit overwhelming, since the differences are not obvious, and they are evolving rapidly, too.

At the time of writing many tools are freely available. We use the following almost every day, and we recommend investing the time to learn them.

Chrome DevTools: Google Lighthouse

Google Lighthouse is a tool that runs several tests against a given URL. The URL can be public or private, and the tests are usually executed directly inside the browser.

The benefit of Google Lighthouse is that it can be run at any time in the development cycle, even before the website is deployed.
Together with the results it also gives a good indication of what can be improved. The downside of Google Lighthouse is that it only executes the tests in the developer's browser, meaning it doesn't take actual user data into account. The report is said to be based on "Lab Data".
If the developer uses a high-end laptop with a fast internet connection, a website can score quite differently compared to users on a mobile phone with low bandwidth. Also, installed browser extensions can influence the report. To have a clean baseline, run the reports in a private browsing window without extensions.

To generate a Google Lighthouse report, open a new private browsing window, open the Chrome devtools (F12), and select the "Network" panel.
Throttle the available bandwidth to "Slow 3G" in the dropdown at the top of the panel.
Then select the "Lighthouse" panel. Always run Lighthouse using the "Mobile Device" setting.
Finally, click "Analyze page load".

Google Lighthouse reports contain many links to documentation about the different performance aspects. Be sure to follow them to understand how to apply the recommendations to improve the page performance.

To read more about Google Lighthouse and learn how to use the recommendations, please visit developer.chrome.com/docs/lighthouse/overview.

Chrome DevTools: Performance Panel

The Performance panel is used to record a profile of what is happening in the browser window for several seconds, and then provide all the information, so it can be analyzed in detail.
A developer can choose if the recording should happen directly during and after page-load, or at any time afterwards. As such it is a very versatile profiling tool.
The downside is that it records a lot of data even in 1-2 seconds, and digging into it requires a pretty deep understanding of how browsers work.

Another thing to keep in mind is that the Performance reports are also based on the browser process itself, not the data of the actual visitors on a life site. Just like a Google Lighthouse report, it is based on "Lab Data".

Even though the panel can be used to analyze what is keeping a site from passing Core Web Vitals, this tool will be more useful to someone writing a full JavaScript application.

To read more about the devtools Performance panel, please visit developer.chrome.com/docs/devtools/performance.

Chrome DevTools: Performance Insights Panel

This new panel in the Chrome devtools is still marked as experimental at the time of writing, so it may look or work a bit differently in the future. In contrast to the "Performance" panel, its focus is on optimizing page loads, which is most relevant for passing Core Web Vitals.
It also tries to provide actionable recommendations, rather than allowing developers to figure out bottlenecks and how to overcome them on their own based on the recorded data.

The generated reports are based on the in-browser process, what is called "Lab Data".

To generate a Performance Insights report, open a new private browsing window, open the Chrome devtools (F12), and select the "Performance Insights" panel.
Select the throttling menu by clicking on "No Throttling" and configure the network to simulate a Slow 3G connection and a 4x CPU slowdown. Then click "Measure page load".

The report on the left hand side of the panel looks almost like the Performance Panel, but on the right, you can see an "Insights" top-to-bottom timeline of the page load process with a focus on the Core Web Vitals.
Click on the items to see more details, potentially with a recommendation on how to improve the situation.

At the bottom of the panel, you can replay the recording.

The report links to documentation about the different performance aspects that are worth reading.

To read more about the devtools Performance panel, please visit developer.chrome.com/docs/devtools/performance-insights/.

Google PageSpeed Insights

This incredibly useful tool can be accessed for free at https://pagespeed.web.dev/.

The biggest difference when compared to Google Lighthouse or Performance Insights is that it uses real user monitoring data in addition to lab data.
Chrome browsers collect anonymized performance data in the Chrome UX Report ("CrUX") database.
This data is used to generate a report on how a website performs for its actual visitors, rather than in the browser of the developer viewing the actual report.
If a website is mainly used on mobile devices or desktops will reflect in the result.

To quote the Google PageSpeed Insight documentation:

Lab data is useful for debugging issues, as it is collected in a controlled environment. However, it may not capture real-world bottlenecks. Field data is useful for capturing true, real-world user experience - but has a more limited set of metrics.

The user-data-based report requires enough data to have been collected by visitors.
Until that is the case, only a Lighthouse lab-based data report is generated. This is just like running Google Lighthouse in the Chrome devtools panel, except that it uses a baseline Chrome browser running on Google-owned servers, which already makes a difference when compared to the often more high-end developer machines.

The full reports contain useful links to the different frontend performance-related topics.

To read more about Google PageSpeed Insights, please visit developers.google.com/speed/docs/insights/v5/about.

Hyvä Performance Tips

The above tools provide many valuable recommendations and insights about image compression, styling, DOM size, third-party scripts, and more.
These apply to any website. When applying the recommendations to a Hyvä store, the following tips and tricks can be helpful.

Avoid huge Alpine components on catalog or CMS pages

Alpine is great if used correctly. If large DOM branches are used inside an Alpine component, it will take a long time to initialize, adding to the main thread blocking time, and hurting performance metrics.
In such cases refactor the code to use vanilla JavaScript, or try to keep the amount of DOM manipulation the component has to do to a minimum.
This means avoiding attributes like x-bind:class (or :class) and methods like setAttribute.

On pages that are less performance critical, for example, the customer account of the checkout, the constraints can be relaxed a bit.

Use x-defer to defer Alpine components

Most Alpine components below the fold don't have to be initialized when the page loads. By adding x-defer="intersect" the page interactivity can be improved.
Be aware though that if it is added to all Alpine components indiscriminately it will increase the main thread blocking time again, so use it with care and test if it makes a difference.
For more information, see the x-defer documentation.

Experiment with preloading

Since release 1.3.7 Hyvä includes an experimental implementation of the preloading speculation API.
It is currently only useful to visitors using Chrome or Edge, but that is the majority on most websites. The feature can be enabled at Hyvä Themes > Experimental > Experimental Features > Enable Preloading Speculation Rules

For more information on the preloading speculation API please see developer.chrome.com/docs/web-platform/prerender-pages and nitropack.io/blog/post/speculation-rules-api.

Lazy load images below the fold

Add loading="lazy" to all images that are below the fold on mobile. It's that easy.

Do not use alpine classes within selectors in .css files

Doing so will bloat the generated styles.css greatly.

Excessive DOM Size

Template tags

If Google Lighthouse reports an excessive DOM size, a common trick is to wrap parts in Alpine.js <template x-if=""> tags.
The browser doesn't recognize the tag, and any contained nodes do not count to the initial DOM size until Alpine is initialized and injects the contents into the page when the x-if condition is true.
This works well, but the downside is that any contents are also hidden from search engines, so they will not be indexed.
Be sure to use this with care.

AJAX injection

Another alternative is to remove part of the page below the fold and load it with AJAX only once a visitor scrolls that far.
The benefit of this approach is that the document actually gets smaller, and thus uses less bandwidth.
It has the same downside as using <template> tags though in that the content is hidden from search engines.