What is critical CSS? How does it work and when should you use it?
- Even better…when should critical CSS not be used?
Here goes another cut-the-crap WordPress performance guide by yours truly.
Innocent question from one of my webhosting clients:
Hey man, quick question: have you ever dealt with critical CSS? I’m trying to experiment with it but often plugins that promise it aren’t very good.
Site’s already crazy fast but if it can be faster then why not? XD
I was so impatient, I responded right away…”It’s not for you. It’s an old ass tactic now coming back in popularity cuz of bloated pagebuilders. You don’t have that problem.”
And not long after I broke down the reasons why, I felt the need to share them on my blog…
How does “Critical CSS” work?
Critical CSS is when your site initially loads only the CSS used for ATF (above-the-fold) content at the top of your site, instead of loading the entire CSS for the whole page. The idea is that by loading only this “critical CSS”, your page would appear to render faster for users while the rest of the page (below the fold) took a little longer to load but wouldn’t be noticed.
This tactic is especially useful when you have so much CSS (let’s say anything above 60KB) that it takes half a second or even longer to process. Remember how internet videos used to work? You couldn’t watch the video until the entire thing loaded! But now with streaming media formats, you could start watching as soon as the first few seconds loaded. Critical CSS works similarly, the page can start rendering once the initial CSS had processed.
Caveats to “critical CSS”
As with everything, there are at least a dozen caveats to this tactic. I’ll list the notable ones:
- WHO determines which is “critical CSS”? – a human coder? Or automated script generator? I prefer hand-coders as they would know precisely which elements are actually above the fold whereas the automated script would only be guessing based on preconceived algorithms. Will that annoying GDPR pop-up be included or not? Will shop icons be included or not? Will all the items in the not-yet-expanded mobile menu be included or not? See what I mean?…too many elements to decide. The worst case scenario is when critical CSS is generated improperly and breaks your site styling/function.
- Critical CSS might hurt your load time for subsequent visits if you have browser cache. Think about it…with browser cache enabled, static assets like images and CSS/JS are cached on users’ browsers and loaded locally (producing the fastest load time). By locking away your critical CSS inline in the HTML document, you are requiring DNS time for that critical CSS on every request. In the case of browser cache, I think critical CSS only helps for that initial visit.
- Your total CSS is so small that splitting it into more parts slows down your site (adding extra HTTP requests) without actually producing perceived faster render times.
- You have so much critical CSS that the added complexity doesn’t give you any noticeable speed increases.
CSS should be render-blocking!
I’m sick of newbies trying to deploy CSS optimization tactics (like CSS combination/merge or critical CSS)!
Let’s get this straight -> CSS by nature is supposed to be “render-blocking”.
It has to be so that you don’t get FOUT/FOUC issues. (Flash-of-unstyled-text or flash-of-unstyled-content is when your content loads before your styling and looks ugly/plain for a split second.)
The only matter now is to reduce the render-blocking impact as much as possible. I hate that it’s even described this way. If it were up to me, I would just call it “CSS processing”. Anyway…
Back in the days, CSS wasn’t used so bloated. A few kilobytes was all you needed to style your entire site. This was easily done because your site was probably designed all at once, by one person, and with the whole picture in mind. Nowadays, websites are built in a very modular way. The theme is designed or chosen in 2016, further customized in 2017. There’s maybe 15-30 plugins; each one designed by different developers, that also come with their own separate CSS.
Guess what all this code spaghetti means? It means because all these little parts are coded at different times and by different developers, they add their own CSS and with many overlapping CSS. For example, your theme comes with button-styling which then gets over-ridden by the pagebuilder button styling and then again later over-ridden by the newsletter pop-up styling. Had you written the code from scratch, all this could have been like 3 simple lines…instead of 9 lines, 6 of them of them over-riding each other.
So moving on!…
Regardless of how you end up with too much CSS (again, l define “too much CSS” as being 60kb or higher), the idea is to reduce its processing time (or in pagespeed terminology: “render-blocking” time).
Methods to reduce unnecessary CSS
- If your CSS is already minimal (below 60kb, preferably below 30kb), then you don’t have to do anything as it isn’t blocking anything.
- If your CSS is huge, then try removing as many unnecessary plugins as possible.
- If you have to keep all that CSS, then rewrite your theme from scratch or refactor the code (basically re-writing your code to be cleaner and more concise). Yes, I’m fully aware most of you non-coders can’t do this yourself.
- Most realistic option for newbies/non-coders – chop up the CSS into smaller files so your site can load quicker instead of waiting for entire CSS to download. This already happens naturally except for when people do silly things like COMBINE CSS (ugh! another annoying tactic used to trick pagespeed tools). Can I just say that the best way to reduce HTTP request is TO ACTUALLY REMOVE THE REQUESTS (instead of doing script combinations—ARGH!) Combining scripts is the equivalent of 5 customers at McDonalds combining their order into one giant order and further holding up the line.
- Or deploy the “critical CSS” tactic. Can be useful if you have so much CSS. But then again, it’s better if you just removed all that crud.
Arguments for (and against) critical CSS?
In favor of critical CSS:
- When you have a ton of CSS and most of it isn’t needed above the fold.
Against critical CSS:
- When you have browser cache enabled. Browser cache already saves static assets (like CSS, JS, images) to the user’s browser so it won’t need to be re-downloaded again. If you use critical CSS and have it inlined in the HTML document, users would have to keep re-downloading this critical CSS on every request. So basically…critical CSS only helps you for the first visit (but slows down all subsequent visits).
- When you don’t have much CSS.
- When you don’t have much content. There’s point in splitting up your requests even further when you don’t have much HTML content or load requests to begin with. Suppose you have only 12 requests and 1kb worth of HTML content, it makes zero sense to add another HTTP request and hurt your overall load time.
- When most of your CSS is needed to render ATF content. If your critical CSS is already 45kb out of 50kb total, why bother splitting that into 2 requests?
- When you have so many pages that it isn’t worth the server processing to generate critical CSS for all of them.
- When you don’t know how generate proper critical CSS for your site.
- When it creates rendering problems.
Frequently Asked Questions (about critical CSS)
What if I do have a pagebuilder? Can I enable it then?
- Having a pagebuilder doesn’t necessarily make you a perfect candidate for critical CSS. What matters most is that you load tons of CSS and most of it is not required for page-rendering. But here’s where it gets tricky. Most pagebuilders DO use all that massive CSS that they load. Or the other angle is that you have a pagebuilder but don’t really use all the crazy options and don’t load much CSS. In both of those scenarios, critical CSS is still not recommended for you.
Can’t I just try it anyway? I’m [desperate] to play with random settings in hope of speeding up my site.
- Yes, you can do anything you want. No need to have my permission. Heck, you can read around and find all the validation you need on a hundred other sites.
But Google says I have “render-blocking CSS”…
- CSS by nature is supposed to be render-blocking (to avoid FOUT/FOUC issues, remember?). I think what Google intended to say is that your CSS is taking too long to load.
- You can’t stop 3rd party CSS from render-blocking. They aren’t loaded from your server. Ain’t nothing you can do about it except to avoid or defer that request.
frank
Hey Johnny 🙂
You do have a point, CCSS (and removing any render-blocking resource) isn’t always easy, but on the other hand; even a <60kb CSS-file will slow down your start render/ first paint time, which is kind of a big deal after all 🙂
Johnny
Hey Frank, nice to see you here! I’m of the opinion that a single 60kb CSS file (browser-cached) will be less hassle than say 2 separate CSS files (8kb CCSS + 55kb CSS). And with even that said…this is more of a matter for newbies vs experts. Anybody on your level could certainly achieve great results no matter what method…but for the average non-techie?…I feel CCSS is more hassle than it’s worth. They’ll end up with even more CSS to load, potentially cause more style conflicts, and still have FOUT/FOUC issues.
Mike
Talking about page builders, here is what they load by default, even if you don’t have any content :
https://oxygen4fun.supadezign.com/the-best-wordpress-page-builders-compared-2019/
(see at the end of the page).
Pretty huge for most of them, and it gets bigger with each update.
Johnny
Yeaup! Bloated as heck!
Mato
What if someone has cloudflare? Does cloudflare cache critical css generated manually? I have an SSG site with cloudflare in front of it and I have critical css manually extracted and the full css loaded later at the closing body tag.
Johnny
If an automated machine service is doing it for you, then it obviously isn’t “manual”.
mato
Did you understand my question? I asked if Cloudflare caches critical CSS. By manually I mean I have the CSS in the head inline and the rest in another file at the footer.
Johnny
Cloudflare caches all static assets. I don’t know where you got the idea that it treats (or even distinguishes) critical CSS any differently from regular CSS.
Diiamo
Hi, “EMAIL” sharing label is invisible when hovering https://picshack.net/ib/0I48XEe5XJ
Johnny
I’ve been meaning to fix that but haven’t gotten around to it. Thanks for the reminder!