Last Thursday, January 16th, I joined TJ Gamble's livestream to answer some PageSpeed related questions. Critical CSS was one of the subjects. Just before the livestream, I published a code snippet to auto-enable CSS critical Path within Magento 1.
In case you missed the livestream, you can still view it on LinkedIn. And in case (and most likely) your webshop runs on Magento 2 instead of Magento 1, read my earlier article about the introduction of CSS Critical Path in Magento 2.3.3.
To simulate this behaviour within Magento 1, I came up with a code snippet to be used within Magento 1, being an improved version of what Magento 2 is doing.
CSS Critical Path
CSS Critical Path is the technique where you inline the CSS responsible for (preferably meaningful or visible) elements above the fold. The challenge is to determine which elements are or rather should be visible on first load.
Render blocking
Render blocking means you are preventing the browser from rendering HTML. The resources have to be downloaded and executed, pausing the rendering-task at that very moment.
By inlining this CSS within the head-section of your product- or category -pages and lazy-loading the external stylesheets, these stylesheets are no longer render blocking. As a result, the browsers of your visitors can start painting right away, instead of having to wait before stylesheets are downloaded.
Why critical CSS?
The user experience gap will only become bigger, as:
- The variation in the number of different kind of devices won't become smaller, think about desktop, laptop, tablet and smartphones, and are all available in different operating system, browsers and versions. That's quite a lot of possible set-ups, as well as CPU to take into account;
- Part of your visitors will move on to the newest devices, while others will still be on legacy devices. This gap will become even bigger when you have an international oriented webshop;
- Some users will be in the city with good coverage, while others might be in the suburbans or even more rural areas;
- The internetplan (speed and bundle limits) of your visitors aren't the same.
Despite these considerations, you want to retain as much visitors as possible, to reduce the bounce-rate and increase conversion. This can be done by giving your visitors the idea that the webshop is loading fast, increasing customer retention. Meet: perceived performance.
Perceived performance
By getting rid of render blocking resources, we can optimize for perceived performance. As a result, visitors will experience a faster loading speed, as (meaningful) elements are visible as soon as the initial HTML response has been downloaded (not completely true, as HTML is being rendered as it is being streamed, but at least sooner without render blocking resources). Elements to paint as soon as possible, could be:
- header;
- company logo;
- product title;
- maybe even product price if it fits within the viewport
Performance metrics
We can use performance metrics to determine where the UX pain is. For example, Google Chrome's Lighthouse is showing you individual metrics, saying something about the impact of TTFB/resources in general, the impact of JavaScript, et cetera. Although not within this scope, the metric closest to perceived performance, will be the First Meaningful Paint or FMP metric (being replaced by Largest Contentful Paint).
Hosting and TTFB
Although the role of the frontend will become bigger and bigger because of the UX gap, we still have a server-side role to take into account. Best practices are obvious: reduce amount of database queries, enable server side caching mechanism. Slow server side response times (and thus TTFB) will slow down any other performance-metric.
The role of JavaScript
There are long articles about the role, or rather cost of JavaScript, such as the one written by Addy Osmani, engineering manager at Google working on Chrome. But let's make it short today.
Today, the main bottleneck is CPU. The cause of this shift is the increase in CSS and JavaScript, as well as more mobile users
Steve Souders at SpeedCurve
As JavaScript is render blocking as well, JavaScript resources should be moved to the bottom/footer of your pages, or you should add a defer attribute. The async attribute could work as well here, but could lead to unpredictable results (because of the difference between defer and
async).
When you don't address JavaScript this way, CSS critical path won't bring you joy.
HTTP/2, push and bundling to the rescue?
Won't HTTP/2 (concurrent downloads), server push (where you can send CSS ahead of time) and bundling fix our issues? The answers are, no!
- HTTP/2
This did speed up experience since HTTP/1, but resources will still be render blocking; - Server push
It's broken, just like HTTP/2 priorization often is broken as well. - Bundling
Yikes, please don't do this when HTTP/2 has been enabled. But yes, resources are still render blocking.
This is where the basic mindset begins and determining the CSS Critical Path with eye for meaningful elements and user frustration (due to layout shifts) begins.
Download Magento 1 CSS Critical Path code snippet
Interested in the Magento 1 code snippet? Fill in the form below to get the PDF with instructions and code snippet right away.
My role
I often say optimizing on the client side doesn't have to be rocket science. It is a matter of mindset as well as know how browsers work and what is important towards UX / onboarding process. So, by addressing perceived performance, we are actually doing several things, such as:
- optimizing the speed (obviously);
- UX, by improving perceived performance and reducing layout shifts with the user in mind;
- UX, by reducing user frustration as they might try to interact while some JS components haven't been downloaded or executed yet;
- SEO, by improving ranking, ad costs as well being on the right side of Chromium's pagespeed badge of shame.
By adjusting this mindset within agencies, I enabled developers to bring focus on pagespeed and keeping track of pagespeed while introducing new webshop features.
I am transferring this knowledge during in-house training and knowledge sessions as well as (often public) talks.