I searched online for tools to extract the critical css of a website for one of my clients, I couldn't find one that did the job so I did so after using Puppeteer locally and then decided to share the solution I used that let's you specify how long to wait after page load to extract the styles; even found a paid one but requested refund after it didn't work.
I’ve been away for quite a while, so just a loud thinking.
With tools such as PostCSS, and servers serving zipped styles across CDN, maintaining a single request to the styles; does it really benefit from breaking up the styles these days?
Also, I’m going to assume, besides the core styles that run a website, anything that is loaded later can come in with its specific styles as part of the HTML/JS.
For the critical CSS thing, we used to kinda do it by hand with some automation more as a toolset to help us decide how much to include (inside the HTML itself – `<styles>`) and then insert the stylesheet. But then, we always found it better to set a Stylesheet Budget and work with it.
Nice one. Would be cool if this also handled responsiveness. The need to dedupe responsive critical styles has made me resort to manually editing all critical stylesheets I've ever made.
I also see that this brings in CSS variable definitions (sorry, ~custom properties~) and things like that. Since critical CSS's size matters so much, it might be worth giving an option to compile all of that down.
> Place your original non-critical CSS <link> tags just before the closing </body> tag
I don't recommend doing this: you still want the CSS downloaded urgently, critical CSS is a façade. Moving to the end of body means the good stuff is discovered late, and thus downloaded late (and will block render if the preloader[0] discovers it).
Non-starter for all but hobby websites since it's incompatible with any content security policy disallowing inline style tags.
Edit regarding replies to this comment: I'm sure many will get a kick out of your workarounds and they're all worth posting in the spirit of HN, however I am talking about CSPs that disallow shenanigans. Carry on though :^)
WordPress plugins and builders like Divi and Elementor has been inserting all css for every page part or component anywhere in the body for years. I hate it. But, thas this critical css means they have beeing doing it right all along?
Critical CSS: 57KB uncompressed (7KB compressed) — tested using this site for performance analysis.
In comparison, many similar sites range from 100KB (uncompressed) to as much as 1MB.
The thing is, I can build clean HTML with no inline CSS or JavaScript. I also added resource hints (not Early Hints, since my Nginx setup doesn't support that out of the box), which slightly improve load times when combined with HTTP/2 and short-interval caching via Nginx. This setup allows me to hit a 100/100 performance score without relying on Critical CSS or inline JavaScript.
If every page adds 7KB, isn’t it wasteful—especially when all you need is a lightweight SPA or, better yet, more edge caching to reduce the carbon footprint? We don’t need to keep transmitting unnecessary data around the world with bloated HTML like Elementor for WordPress.
Why serve users unnecessary bloat? Mobile devices have limited battery life. It's not impossible to achieve lighting fast experience once you move away from shared hosting territory.
(It lets me uncheck the "display: none" rule in the developer tools to get a baseline grid overlaid on the site to make sure things line up. They don't anymore because I forgot I had that in there until I saw it now!)
Assuming you are using an atomic CSS based framework like tailwind, this would be unnecessary right ? Since all the CSS class names are anyways in-lined with the element.
When I was doing performance examinations from localhost I found that CSS was mostly inconsequential if written at least vaguely efficiently and requested as early as possible from the HTML. By completely removing CSS I might be able to save up to 7ms of load time, but that was extremely hard to tell because that was well within the variance between test intervals.
the amount of tiny tweaks that stack up in css is kinda nuts tbh – always felt like chasing performance can be endless, makes me wonder if any dev really feels satisfied with their setup or if it's just a bunch of tradeoffs
Feels like premature optimisation to me. Are there really cases where the CSS is so complex or the page loads so many resources that this effort is worthwhile? Maybe with the most complex web apps, I guess, but for almost all cases, I would have thought writing clean CSS, HTML, and JavaScript would render this unnecessary or even counterproductive.
{"error":true,"name":"Error","message":"css should not be empty","stack":"Error: css should not be emptyn at module.exports (/usr/src/app/node_modules/penthouse/lib/index.js:206:14)n at file:///usr/src/app/server.js:153:31n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)"}
Whoops, you're not connected to Mailchimp. You need to enter a valid Mailchimp API key.
Our site uses cookies. Learn more about our use of cookies: cookie policyACCEPTREJECT
Privacy & Cookies Policy
Privacy Overview
This website uses cookies to improve your experience while you navigate through the website. Out of these cookies, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may have an effect on your browsing experience.
16 Comments
stevenpotts
I searched online for tools to extract the critical css of a website for one of my clients, I couldn't find one that did the job so I did so after using Puppeteer locally and then decided to share the solution I used that let's you specify how long to wait after page load to extract the styles; even found a paid one but requested refund after it didn't work.
Feedback welcome, it's free for now.
Guptos
[flagged]
Brajeshwar
I’ve been away for quite a while, so just a loud thinking.
With tools such as PostCSS, and servers serving zipped styles across CDN, maintaining a single request to the styles; does it really benefit from breaking up the styles these days?
Also, I’m going to assume, besides the core styles that run a website, anything that is loaded later can come in with its specific styles as part of the HTML/JS.
For the critical CSS thing, we used to kinda do it by hand with some automation more as a toolset to help us decide how much to include (inside the HTML itself – `<styles>`) and then insert the stylesheet. But then, we always found it better to set a Stylesheet Budget and work with it.
lelandfe
Nice one. Would be cool if this also handled responsiveness. The need to dedupe responsive critical styles has made me resort to manually editing all critical stylesheets I've ever made.
I also see that this brings in CSS variable definitions (sorry, ~custom properties~) and things like that. Since critical CSS's size matters so much, it might be worth giving an option to compile all of that down.
> Place your original non-critical CSS <link> tags just before the closing </body> tag
I don't recommend doing this: you still want the CSS downloaded urgently, critical CSS is a façade. Moving to the end of body means the good stuff is discovered late, and thus downloaded late (and will block render if the preloader[0] discovers it).
These days I'd recommend:
[0] https://web.dev/articles/preload-scanner
jer0me
Kind of funny that the agency that made this has a loader on their site.
rado
Not working in Safari. Says ‘done’ but Generated CSS box remains empty
sublinear
Non-starter for all but hobby websites since it's incompatible with any content security policy disallowing inline style tags.
Edit regarding replies to this comment: I'm sure many will get a kick out of your workarounds and they're all worth posting in the spirit of HN, however I am talking about CSPs that disallow shenanigans. Carry on though :^)
worthless-trash
Why worry about this when companies pakage 10mb of javascript. Is this really where the problem is ?
n3storm
WordPress plugins and builders like Divi and Elementor has been inserting all css for every page part or component anywhere in the body for years. I hate it. But, thas this critical css means they have beeing doing it right all along?
todotask2
When I tested mine, I got the following:
Built on Astro web framework
HTML: 27.52KB uncompressed (6.10KB compressed)
JS: <10KB (compressed)
Critical CSS: 57KB uncompressed (7KB compressed) — tested using this site for performance analysis.
In comparison, many similar sites range from 100KB (uncompressed) to as much as 1MB.
The thing is, I can build clean HTML with no inline CSS or JavaScript. I also added resource hints (not Early Hints, since my Nginx setup doesn't support that out of the box), which slightly improve load times when combined with HTTP/2 and short-interval caching via Nginx. This setup allows me to hit a 100/100 performance score without relying on Critical CSS or inline JavaScript.
If every page adds 7KB, isn’t it wasteful—especially when all you need is a lightweight SPA or, better yet, more edge caching to reduce the carbon footprint? We don’t need to keep transmitting unnecessary data around the world with bloated HTML like Elementor for WordPress.
Why serve users unnecessary bloat? Mobile devices have limited battery life. It's not impossible to achieve lighting fast experience once you move away from shared hosting territory.
kqr
Hm. When I tried this on my site it retained a debugging element that is decidedly not required, but adds a lot of bytes to the CSS:
(It lets me uncheck the "display: none" rule in the developer tools to get a baseline grid overlaid on the site to make sure things line up. They don't anymore because I forgot I had that in there until I saw it now!)
lenkite
Assuming you are using an atomic CSS based framework like tailwind, this would be unnecessary right ? Since all the CSS class names are anyways in-lined with the element.
austin-cheney
When I was doing performance examinations from localhost I found that CSS was mostly inconsequential if written at least vaguely efficiently and requested as early as possible from the HTML. By completely removing CSS I might be able to save up to 7ms of load time, but that was extremely hard to tell because that was well within the variance between test intervals.
https://github.com/prettydiff/wisdom/blob/master/performance…
gitroom
the amount of tiny tweaks that stack up in css is kinda nuts tbh – always felt like chasing performance can be endless, makes me wonder if any dev really feels satisfied with their setup or if it's just a bunch of tradeoffs
oneeyedpigeon
Feels like premature optimisation to me. Are there really cases where the CSS is so complex or the page loads so many resources that this effort is worthwhile? Maybe with the most complex web apps, I guess, but for almost all cases, I would have thought writing clean CSS, HTML, and JavaScript would render this unnecessary or even counterproductive.
GavinAnderegg
Neat idea. I tried it on my site (https://anderegg.ca/) which already inlines its CSS, and got an error from the underlying library (https://www.npmjs.com/package/penthouse):