6 ms·
UnCSS: Remove unused styles from CSS
- mrschwabe 10y agoClutch timing! Been working on several projects amassing a multi-purpose stylesheet (currently ~600 lines) having already conceded that a tool which accomplishes exactly this would be needed. Edit: seems overkill, the theoretical solution I had in mind would just take a few arguments; ie: trimCss mybloated.css mypage.html > mytrimmed.css
- bl4ckdu5t 10y agoAm I missing something? UnCSS has been for about 3 years now. http://bit.ly/uncss http://bit.ly/uncss by addyosmani
- ptrptr 10y agoDifferent projects, duplicating work is also big issue that need to be solved IMO.
- scandox 10y agoI guess this is being downvoted because he links to the wrong repo (i.e. the grunt edition of the same project) but the point seems fair. I've been using unCSS about 2 years so it is interesting that this discussion is happening now and that people seem surprised by its existence. Perhaps just a symptom of too much JS everything.
- booleanbetrayal 10y agoI've been wanting to tie this up with Casper automation in order to get coverage on dynamically generated content. The hard part is just ensuring the content path is adequate. We do something similar with PhantomCSS already, but it's definitely a tighter scope.
- robotjosh 10y agoThis is a problem I thought would be solved by 2017
- asimpletune 10y agoI made a similar tool, although it doesn't load the page in a browser to remove unused styles. https://www.npmjs.com/package/uselesscss https://www.npmjs.com/package/uselesscss
- AliAdams 10y agoI wonder what the performance increase would be of loading one big CSS file on the first page load and serving from local cache from then on, vs loading a smaller but different CSS file for each page you visit. My impression is that number of requests is a more critical optimization than file size (at least when serving CSS sized files)
- ino 10y agoServing the page with inlined CSS also has the compression benefit of many html ids and classes being repeated in the CSS.
- tkadlec 10y agoReally depends. How big is the once CSS file you're loading and how much of the CSS is common from page to page? If 20kb is for a specific component on one or two, less-visited pages, then it probably doesn't make sense to lump everything together. A fairly safe default starting point would be: 1. Tiny subset of inlined critical CSS (See https://www.smashingmagazine.com/2015/08/understanding-critical-css/ https://www.smashingmagazine.com/2015/08/understanding-criti...) 2. Asynchronous + rel=preload loading of the main CSS of your site 3. Then, if there are hefty chunks of CSS for specific pages only, bring those in on those pages. This changes a bit if you're using HTTP/2. Then the multiplexing makes it beneficial to break the CSS into a few smaller files instead of one big one. In the end, you probably just have to experiment and test. :) No guaranteed "this is best" approach here.
- rasz_pl 10y agocaching is out of style nowadays, you lose precious user tracking, not to mention dynamic web. Its as bad as DNS TTL (some keep it at couple of minutes or lower).
- madeofpalk 10y agoIt's going to depend a lot on the type of site you're building. Thankfully frontend pipelines like React + Webpack makes it fairly easy to test this out. We spiked out generating individual JS + CSS for each view but ultimately found it wasn't worth it - individual views amounted to very little code with the bulk of the filesize taken up by the common 'core' of our application, and dependencies. We scrapped this specific idea. What we did end up doing, however, was create a seperate stylesheet just for things required on the very minimal landing page and inject that straight into the <head>, which gave us significant speed improvements.
- eloff 10y agoFinally! I've been wanting this for a decade - but not badly enough to try to build it myself.
- thora 10y agoThis is great! I'm happy to see PostCSS proving to be a creative platform for web development.
- jwr 10y agoI've been hoping someone would write a similar tool, but using a browser, so that I could run a webapp, click around (using a checklist, to cover all of the views) and get a resulting list of used CSS rules from the browser. That would have the advantage of supporting complex webapps written in any language/environment.
- aslushnikov 10y agoThere's a "Coverage Support" experiment in Chrome DevTools which does css + js coverage in a way you describe it. The CSS part was shown on Chrome DevSummit 2016 [1] [1] https://www.youtube.com/watch?v=HF1luRD4Qmk https://www.youtube.com/watch?v=HF1luRD4Qmk
- laurencei 10y agoStarts around the 18min mark in the video.
- anotheryou 10y agoStates can quickly become complex. Like styles for a logged in user with a 3-years-membership badge or styles for a placeholder that only new users see. Or styles for a CMS module that is currently not in use (e.g. for open positions in a company). I wonder what the least used, yet still used CSS is I ever wrote (relative to project traffic). Maybe some feature a Client requested, I knew he would never really use, but he insisted on (deep linking to some modal for a facbeook post or something).
- jsnathan 10y agoIt might be hard to do for an existing site of considerable size, but for new sites it could be done incrementally as features are added.
- eli 10y agoI've used this one before https://addons.mozilla.org/en-Us/firefox/addon/css-usage/ https://addons.mozilla.org/en-Us/firefox/addon/css-usage/
- KevanM 10y agoHow easy would it be to get this to work with something that spiders a site, so it generates a CSS file dynamically for a whole site instead of manually feeding it URLs?
- ry_ry 10y agoHave used tools like this before, and invariably end up accidentally stripping styles from an <insert JS UI lib> component with a dynamically assigned className or something equally silly. It's such a hard problem to solve and the Stylesheet Snowball is one of the most frustrating pieces of technical debt a large site can pick up. It makes me wonder if scoped CSS modules, despite fundamentally breaking CSS with their hyper specific hybrid BEM-class-ids might be the best preemptive solution even when you're not scaling up to massive SPAs. Edit. Meant CSS modules, wrote CSS components. I am not a clever man.
- _nalply 10y agoI agree, it's a hard problem. Perhaps run a test-suite with UnCSS? If you still accidentally strip styles then the test-suite is not complete.
- dlo83 10y agoNot a bad idea.
- Shinchy 10y agoThe advent of Sass and Nesting helped an awful lot, but there is still much to be done.
- madeofpalk 10y agoThis is already theoretically solvable with CSS Modules. Because you 'statically' import your CSS (class names) as an object, which can't/shouldn't change after build, you could run an analyser to remove any unused classes from the stylesheets. Essentially tree shaking for CSS.
- noir_lord 10y agoI used BEM everywhere on the front end of a project, at the time I didn't really like it very much. I came back to that project 7mths later and I could find everything exactly where I left it, I realised that past me had made a reasonable choice for the future. Now I hold my nose and use it (or something like it) everywhere. Even b-<somefoo> { <otherstuff> } helps hugely, I just wish there was an easier way of stopping accidental stomping from other selectors outside b-<somefoo>.
- Grangar 10y agoWould this work if you print classnames with php?
- cmg 10y agoSure, you'd need to point the files argument at your website on a server, though - you couldn't just target a .html file.
- msiebuhr 10y agoAFAIK, this could also be written as a transform in AssetGraph [https://github.com/assetgraph/assetgraph https://github.com/assetgraph/assetgraph], which does all of the loading, parsing and traversing for you. At least the given description reads like the internals of the population/loader-system in AssetGraph. As an added benefit, you'll get de-duplication, minification, inlining (with fallbacks) and, with a little work, image-spriting thrown in almost for free. If you want to play around easily, take a look at https://github.com/assetgraph/assetgraph-builder https://github.com/assetgraph/assetgraph-builder
- dalkur 10y agoI've done something similar nearly two years ago[1]. The problem is rather difficult, especially with all the JavaScript frameworks in existence right now. I've tried to build a state machine for handling those frameworks but never got around to finishing it. There's basically and endless amount of combinations one can do, thus you probably want to limit depth or something. You also have to be able to detect ::after and similar kind of selectors, which isn't always straightforward with querySelector and needs quite a bit of cleaning. I ran into a few other (edge) cases, which I cannot remember right now. Nonetheless, it is a challenging and fun problem to solve. [1]: https://github.com/Kevin-A/css-detector https://github.com/Kevin-A/css-detector
- egeozcan 10y agoMy naive opinion is that this should be done by the browser, perhaps in the developer tools. You would be marking a session as "integration tests" and at the end it would give you a simplified css file without the unused rules during testing.
- dalkur 10y agoI wholeheartedly agree with you. That would be the ideal solution, because the browser is already doing the passes over the CSS rules.