It boggles the mind that we style bikeshed over CSS. Is it honestly, truly, and pragmatically worthwhile to spend all this engineering effort manipulating, culling, tree shaking, modularizing our CSS? Pre-load that, inline this, async-load that, and what have we got for it? A web full of wiggling content, slow CDNs, dozens of requests, and an experience of a mis-timed, slow loading web of bullshit.
Deliver less CSS in the first place, be pragmatic, load it as one file when the user hits the website, from the same server they got the HTML from. Bam, lightning fucking fast, like it was before we invented all these new problems.
The brief flash of your half-styled website is useless to me. Block rendering until the CSS is done. I don't enjoy looking at half an interlaced video frame, or 100px of a 200px image, just show me the finished product.
The content wiggles and asynchronous bullshit is what makes your website -feel- slow, even if you managed to trick Google into thinking it loaded quickly.
You don't have to ever think about this stuff if you use a component-driven frontend framework like Vue w/ Vite (or Webpack).
The general design: you use one global .css file for your shared styles (app.css) and then each component has their own inline CSS.
Vite will automatically extract each component JS and CSS in tiny files and only load them when you visit a page with the specific component.
This all happens automatically and you can cleanly organize your project by keeping the styles close to the view template and logic (often the same file has the template, <style> and <script> which each get extract automatically into bundles). The .css/.js filenames match the component name which makes debugging easier too in dev console.
HTTP2 handles loading 20-100 small files like nothing and with large SaaS apps usually only have tons of components that rarely get used, so no need to load them all for every page.
If you had to think about this stuff, manage the tooling, and customize then it would be overhead, but otherwise with frameworks it's pure benefit.
That's such a tool complexity that most people don't need and probably shouldn't bother with for what is often a microoptimization.
I assume this is why a lot of pages do it: SEO over UX. If they cared that much about user experience the ads and tracking would be gone before worrying about CSS in this way.
I have good news for you: https://web.dev/critical-rendering-path-render-blocking-css
CSS is already a render blocker.
A lot of new approaches atomically separate the CSS and JS into dozens of smaller files that load in as the parts of the website that need them load in. Critial CSS is likely also a response to the issues that this approach creates.
As the article alludes to, they're ideas that makes total sense clinically, but falls short really quickly in practice.
If you use a static page this isn't as relevant. It can become significant for single page apps, especially if you dynamically load CSS.
I know I'm talking against industry opinion, but I don't believe browsers are the right platform to be loading things on the fly as the user needs them. It's 50-300+ms absolute best case, plus processing time. It's going to feel bad.
Is there a replacement for CSS Modules' "composes" keyword? Tailwind has @apply, but that defeats the purpose of a utility framework somewhat.
It seems to have a lot of the benefits of Tailwind but better integration with Typescript.
Assume that I know _nothing_ about Tailwind, sell it to me. I'd appreciate it. Thanks.
YES! It affects e-commerce conversion rates measurably.
Great point by the author: "make sure it’s the right thing to focus on." Hobby site? Don't care about FOUC. E-commerce? It's a game-changer.
> The brief flash of your half-styled website is useless to me
Not to the rest our users though! Are you on a 3G connection in a third-world country? If not your experience may be not be shared but every user.
My core industry is e-commerce, have been doing it for over a decade. Our fastest sites are the fully cached, single CSS file sites. You get sent a small amount of CSS and HTML, and you are off to the races. Javascript comes later, and is not necessary to operate the site until checkout.
What kills a sites speed for us is usually shitty CDNs and bloated assets, we don't have those. There isn't a single e-commerce platform popular today that I feel does this well, but that is because they are all enterprise platforms full of enterprise features.
The current best performant way to load JS is asynchronously as documented at https://web.dev/efficiently-load-third-party-javascript/.
And the best way to load CSS is with Critical Path CSS + Async CSS as documented at https://web.dev/defer-non-critical-css/.
The easiest way to generate Critical CSS is https://github.com/addyosmani/critical where you may suggest multiple resolutions.
I have found https://github.com/addyosmani/critical-path-css-tools to be a great resource to master critical path CSS which improves page render speeds. It helps build fast rendering sites, sometimes even sub-second renders given you have a low latency backend.
Is advice different than what you prefer "misleading?"
Anyway, he doesn't actually weigh in on marking JS with `defer` or `async`. And the article is directly contesting preloading the styles, given his note on race conditions with `media` switching. Moving the CSS before the `</body>` closing tag is genuinely a way to really defer your CSS.
> Why would we ever put non-Critical CSS in the <head> in the first place?!
To this point from Harry, I find myself skeptical that anyone's really going to want to do that. Getting layout jank / cumulative layout shift fixed when the main stylesheet is applied is a sisyphean task.
I have not run into layout janks when I have used critical path CSS. I'd look into other tools/settings while extracting the critical path CSS if this would happen to me.
That has to be a typo, right? Or sarcasm?
I weep for what we’ve all done to the beautiful speed and simplicity of the web.
Not disagreeing with you though - it's amazing how much bloat we've added. Nobody seems to get just how fucking fast the web actually is. Take a look at Figma or Linear if you want to see products that truly care about performance.
This script they use to load the async JS can also be racey and it’s far better to put the link to noncritical styles at the bottom of the page
Agree on the async JS part but I guess browser makers will solve it soon.
He says if you’ve got other blocking scripts / stylesheets in the head then there’s no point using critical CSS
Inlining critical CSS is madness for any project that is above a certain scale. Maybe you can do it for a single page, but in my experience the results are not worth the effort. You can make your site exceptionally fast without it.
Any page complicated enough to need critical CSS extraction is probably also going to take 50-100ms to render and transfer to the user. Just send the headers before you render and the client will probably have finished downloading them by the time you're done.
If clients are on a crappy network, critical css is even worse of an idea because they'll scroll down and get a broken page for 5 seconds
Every HTML file should start with: doctype, html tag, head tag, charset meta tag, title, stylesheet link tag. A couple of those tags are even optional.
Most annoying is fancy "loading" screen before page load.
Skip that fancy loading screen/spinner page and your site is already faster.
I build a lot of landing pages so there are very few multi page visits.
If you're passing your Core Web Vitals scores, there is no further ranking signal.
Transcribed from a 2021 Q&A with Google engineers
> beyond that point [of a good threshold for all Core Web Vital metrics], you don't get additional boost for reaching it even better. Like if you have your LCP at two seconds and you get it all the way down to one second, um, we've kind of publicly stated that that will not increase your ranking
I have found that keeping my code short and getting it all out in 1-3 HTTP request is the optimal performance strategy.