Improved pagespeed: Critical CSS introduced in Magento

As of version 2.3.3, Magento introduced CSS critical path. Users will experience a faster loading product-page when applied (correctly)!

Magento adopting the critical CSS approach is great new (minor) step towards improved perceived performance. This is why: In the basis, as soon as the initial HTML document is received by your visitor's browser, all other non-deferred and non asynchronous resources are render blocking.

Render blocking resources

This includes JavaScript and CSS. Render blocking means, the browser will stop rendering text to be displayed, when it comes across external resources.

While parsing from top to bottom (or, from head to footer), such external resources delay rendering, resulting in delay of the First Meaningful Paint metric and thus perceived performance. This will reflect on user experience as well as your webshop's conversion and revenue.

JavaScript as main culprit

The biggest bad-boy has been JavaScript, when it comes to render blocking. JavaScript has to be downloaded as well as compiled and parsed, resulting in extra performance-impact compared to an equal kilobytes of image or CSS. Don't solely take my word for it though, and read Addy Osmani, Google Chrome's engineering manager, article about the cost of JavaScript.

Moving JavaScript to the footer

This can be solved within Magento, by moving JavaScript requests to the footer. Obviously, depending on how JavaScript was used, this should be done with some prudence. Although the Lighthouse FMP metric most likely improved, your Time to Interactive metric often deteriorated. Although browsers use resource scanner techniques, often already detecting and downloading referenced files, this won't work when files are loaded using requireJS. To solve this, one could use resource hints.

More on improving JavaScript within Magento at integer-net.com.

Further improving pagespeed with critical path CSS

When JavaScript has been moved to the footer (or just has been deferred) and you managed to achieve optimal TTFB as well, you're ready for the next phase: critical path CSS.

While a good TTFB doesn’t necessarily mean you will have a fast website, a bad TTFB almost certainly guarantees a slow one.

CSS Wizardry

JavaScript can be render blocking, but CSS can be render blocking too. As a matter of fact, it often is. At the end, you don't want to show an unstyled productpage to your webshop visitors, so you (Magento) throw in an external CSS file before any HTML is being rendered by the browser, introducing a render blocking resource. You can solve this by inlining your CSS, so no external request is neccessary anymore to start painting the page (by your browser, that is).

Inlining all CSS versus partial CSS

Just like deferring JavaScript, there is more to it when applying critical path CSS. You could save some time and inline all CSS. Although, some e-commerce solutions end up serving pages with an increased document-size of 633%. Yes, looking at you, DeOnlineDrogist (article in Dutch).

Obviously, this matters as it takes more time before the file can been received by the browser. While you think you improved the painting time, the loading time before that point just got worse.

Partial CSS it is, then! We're not completely there, though. You want to enable the browser to start painting the important bits, being the content above the fold. While the browser can start painting right away, you can configure your webshop to start downloading the complete external CSS file in the meanwhile. In other words, lazyload your CSS.

Magento's CSS critical path challenges

Obviously, you may encounter some challenges we ran into as well when we first introduced CSS critical path within our solutions and advices.

Reduce productpage layout shifts

Did you ever try to click a productimage or maybe a play-button to start the video and ended up clicking on another product link, accepting cookies or even opening an advertisement?

You don't want to have your content jumping up and down while external CSS is done downloading, and your visitor's browser is repainting the page. Layout shifts will result in visitor frustration, impacting user experience and thus conversion. For example, fonQ is applying critical CSS as well. Layout shifts happens within fonQ productpages though, is what I discovered and wrote about in Dutch on LinkedIn.

Reduce render blocking resources

Didn't we just eliminate the 'render-blocking resources' issue when enabling Magento's CSS critical path? Maybe so, but did you put other external resources within your critical CSS? You may consider these as render blocking resources on it's own. For example, background-images or custom (Google) fonts:

  • use the JavaScript FontFace API to lazyload fonts, and obviously allow visitors to start reading in the meanwhile;
  • defer background-images (or large base64 inlined strings) to your non-critical stylesheet.

CSS selector inheritance

There is a reason Magento is advising the following:

Do not duplicate styles in critical.css and non-critical style sheets.

By default, inline CSS will be prioritized over external CSS when your browser is applying the styles. If you want to change CSS using the external CSS file, you better add some importance to your CSS declarations. This can be done adding the CSS !important property.

As this is considered an ugly workaround, I would advice making your CSS selector more powerful by prefixing the selector with the html or body selector.

Magento's CSS critical path performance gains

Within the developer docs, Magento is stating that:

  • the time for loading render-blocking resources decreases substantially;
  • the first meaningful paint time (FMP metric) improved from 3.5 seconds to 2.3 seconds;
  • the speed index increased by 0.8 seconds;
  • the PageSpeed Insights score improved by 5 points.

The real improvements totaly depends on your specific situation as well as devices used by your visitors. We are used to achieve a mobile FMP between 0.9 and 1.2 seconds when applying critical path CSS. Circumstances are different though.

Magento SSR catching up on CSR?

Does inlining CSS within Server Side Rendered solutions (SSR) out-run Client Side Rendered solutions (CSR) such as PWA when it comes to performance?

Although CSR is always render blocking as content can only be shown as soon as JavaScript has been downloaded as well as parsed (and fetching the actual contents and adding them to the DOM), an SSR Magento webshop will need more performance improvements to become a competitor to CSR solutions.

Enabling CSS critical path is a step into the right direction. At the same time, our SSR solutions are still outrunning CSR solutions when it comes to pagespeed and (perceived) performance. Magento's own frontend has to many performance pitfalls though, to catch up on CSR solutions within a few new features or implementations.

How about other e-commerce solutions?

Performance gains within e-commerce solutions other than Magento, will vary per platform. It would need investigation, maybe even investigation of multiple shops per platform, as no webshop is exactly the same.
However, as I sometimes create Proof of Concepts, I do know what the performance gains would be within Shopware 6. As the headless architecture of Shopware 6 already laid the basis for an optimal pagespeed, relative performance gains will be much higher.
For example, Magento's FMP metric will go from 3.5 seconds to 2.3 seconds. Within Shopware 6, the 3.7 seconds FMP metric became an impressing 1.0 seconds.

Further critical CSS considerations

You can do more do to improve the way critical CSS is being applied:

  1. by focussing on specific, often box-model related CSS properties, developer time will decrease and will make it less hard to implement critical CSS;
  2. You should also inline CSS page-type dependant. Your product-page will use other CSS than your category-listings;
  3. Lazyload your iconsets, such as FontAwsome, using resource hints to start the download in advance;
  4. Consider omitting inlining CSS on following page hits within a session. This way, your content-size and thus content-download for subsequent pages will decrease, improving on-site performance.
    You do need a work-around on Magento's advice of not duplicating styles in critical.css and non-critical style sheets.

Obviously, we implemented these considerations within the solutions we build at Blue 2 Blond and came up with own best practices to address newly emerged challenges.

Support and more info on Critical CSS

At the agency I work as well (Blue 2 Blond), we are already applying critical path CSS for about 3 years. We automated this process within the CMS we use. At the same time, I am advising this technique with its best practices towards e-commerce agencies, when I am asked to audit or optimize the performance.

Want more info? Attend one of my talks, next talk being on Tuesday, November 26. Need help implementing it right away? Shoot me a message!

Let's improve together! Pagespeed video's