Hacker News new | past | comments | ask | show | jobs | submit login
Mincss "clears the junk out of your CSS" (peterbe.com)
122 points by syquek on Jan 22, 2013 | hide | past | favorite | 47 comments



Too bad I didn't catch this while it was still on the front page.

I wrote Helium CSS a few years ago, https://github.com/geuis/helium-css.

There are many problems with the approach being taken with MinCSS that are reflected in how Helium was constructed.

1) Server-side parsing is brittle. Using regex's for this is a no-no. Helium uses document.querySelector in the browser to really test if a selector matches or not. It even has Sizzle for older browser support.

2) Different css is used to target different browsers, or at least different capabilities. Running this server-side doesn't tell you which browser some totally valid css is meant to be used for.

3) Removing un-matched css rules by default is a no-no. Again, tools like this can be clever but they're never smart. It takes the engineer's eye to say, "This is something I actually need to keep" or "Yup, remove this".

4) Helium works in the browser. This lets you easily run it across multiple browsers that you need to support.

You could make a headless browser that uses Helium, but you're going to be limited to Webkit (phantomjs). Its a thought I've had, but never really thought it was worth the trouble of building such a limiting system.

I encourage anyone who needs a versatile tool to try Helium. Feel free to contribute patches and stuff.


The problem I have with these CSS mini programs is that a 'dynamic' site might not always load the css on each page, unless under certain specific circumstances.

i.e. what about ajax calls that result in a new div showing?

or a responsive CSS file with media queries depending upon the size of the screen?


I see it as:

[] You feed in all URLs at once;

`urls = ["/", "/sign_up/", "/about/",]`

[] It pre-proccesses also JS files and tries to match CSS selectors as well. That would work for jQuery and Zepto!

`$("#foo").html($("<span>").addClass("bar"))`

Edit: Okay, that won't work for `addClass`! :)


When dealing with a dynamic site or complete web application I think this would work best when tied into Selenium tests (or a similar integrated test framework).


How about running it as a background to the website, over say, a month, at the end of which you'd have pretty good confidence that you'd have hit all paths.


This is an idea I am currently working on, similar to SitePoint's old "Dust Me Selectors" plugin for Firefox, but running in the background for all selected sites until a set amount of time or the user is happy that they have exhausted all dynamic functionality on the site.


How about running it as a plugin or something for a suite of functional specs for the website ( if it has one! ). Functional spec's by definition should run all the paths that a user can take, so it should give a pretty good idea of the css that is used.


oh cool - i'm very interested in this. Can you please email me? My email is in my profile.


Yeah, you could have a proxy that saves the whole HTML with its URL for every hit. Then run an analysis after a couple of days and you should get a pretty good idea.


What about a program into which you could feed your pre-processed dynamic documents (php, asp, etc) along with the CSS? I could see myself using that.


The problem is there are often too many variables, i.e. what if a username is "blue" for a boy, "red" for a girl (or something like that).

And PHP etc is too dynamic.

Personally I think the 'best' option is a program which 'records' you using the site, and as a Dev I could use my site for like 30mins, touching each point of key functionality. Then at the end, review what sections of CSS were never used, and pick and choose what to discard based upon that (i.e. I can manually then check for fringe cases I might know of).


A few years ago I wrote a python script which does this and more. It inlines the CSS to the page and reduces it to only the used CSS rules [1].

Additionally, my version can also inline the page images as base-64 encoded blocks.

Cheers!

[1] https://github.com/jaytaylor/python-inlineify-html


That looks awesome! Had I known about this I might not have built mincss. Now, I can see other benefits with mincss plus it was fun writing it.

Check this out for a use case where I apply mincss and gain a massive performance boost: http://www.peterbe.com/plog/mincss-in-action


BTW, I like your wget.py. Did you write that? I suspect I've seen it before.


Thanks! I did write it, and I think I've also seen somebody else's "wget.py" in some other python project before, though I can't recall where. At any rate, I've found it an extremely useful tool in a multitude of different contexts.

Here is a link to my latest version of it:

https://gist.github.com/4596861

At this point it has become less simple and more versatile.

Enjoy!

-Jay


I literally hacked a small script that did this 1 hour ago, but using data from Dust-me Selectors[1].

Having a proper tool to do this is great news!

[1] https://addons.mozilla.org/en-us/firefox/addon/dust-me-selec...


To echo other sentiments on this page, how does this work with a one page, ajax application?

The other issue, is that it is all to often that user events trigger the adding, subtracting or refactoring selectors.

How does this handle these scenarios?


This is exactly the point I was coming to make. I like the idea of Mincss, I have even considered making something like it before, but the problem is that if you are adding and removing dom elements with JS then I doubt this program would be able to correctly identify them all and would accidentally clear out CSS that your site needed.

That said, I am sure that static sites/non-JS intensive sites might be able to use this.


Sorry for having to say this, but read the article. It explains there the predicament of using (or rather, not using) Javascript and/or complex AJAX.


I wrote something simliar a while back called CSSess[1]. It's entirely JS and runs in the browser. It's based on yet another project called Helium[2]. The primary difference is that it crawls your site and checks over multiple pages. This is a must have feature for pretty much all sites.

I've been meaning to port it to node and run it with a headless browser. Contributions are always welcome.

1: http://cssess.com

2: https://github.com/geuis/helium-css/


Have you considered combining it with a headless browser, like phantomjs, or with node.js + jsdom (a js based DOM that can run jquery)?


I've been wanting to make it headless for a while, just haven't gotten around to it yet.


I was thinking about this earlier today and how helpful it would be to just not worry about deleting CSS I didn't need. Nice!


I am using the CSS Usage extension [1] for Firebug as a tool for this.

Quote:

How does it work?

- Open up the first page of the site you want to check and press the "Scan" button in the "CSS Coverage" Firebug tab.

- In case of a rich (Ajax or DHTML) site, open up as many divs/popups/tabs in the page as possible and press "Scan" again.

- Visit other pages of your site and press "Scan" again.

Each time you press "Scan", the CSS files that are included in the current page are shown with the number of times the rules has been found applied on your page before it.

[1] https://addons.mozilla.org/en-us/firefox/addon/css-usage/


That looks really cool! I'm impressed. That looks like a great tool for manual inspection when there's a lot of Javascript and conditional loading at play.

I installed it.


Heh, I had pretty much the exact same idea in december as well, and produced a system based on Compass/SASS which does a final pre-process step before CSS output, which attempts to remove any unused rules.

Managed to get 100kB of CSS down to about 2kB for the single-page site I was using it on.

Like the author here, I didn't get into exploring how to make this work effectively on a large site with a number of dynamic pages - the only thing I added for this type of approach was to provide a whitelist.


Very cool project!

Would be nice if you could browse through the proxy for a bit and have it record the overall usage of CSS for your site.


Firefox will show me what CSS applies to each entity and what attributes result. I'd like something that gave me the same information textually so I can tweak the CSS, e.g. simplifying specificity without intending to change the end result, and check for changes, e.g. diff(1). Anyone know of such a thing?


Hey just fyi, I didn't develop this, just found it online and wanted to share here. I'll let the developer know.


Thanks for sharing.


Is it feasible to find superfluous statements?

Ex: A line of CSS that sets text color of li tags to something, but every li tag already would be that color because of a CSS statement for body.

I'm guessing it'd be hard to build something useful and correct, but I think it'd be an interesting extension of this idea.


So if I have a large site driven by a web content management system and each page uses different parts of the css, how can we leverage this? Does it mean we have to generate different css files for each page? or have a dynamically generated css file for each page?


Your choice.

You can feed mincss a bunch of different URLs and or different .html files and it'll work out the CSS in that. (Note: even if you feed it the raw HTML as a string you need to give it a URL) Or, you do one page at a time. However that's slow and will only be an option if you have serious caching. See http://www.peterbe.com/plog/mincss-in-action


You can't. The only way for this tool to be of use is if you have a tiny amount of pages that you can run it against.


This used to be common practice for front-end developers, back when Firefox was the most popular browser: https://addons.mozilla.org/en-us/firefox/addon/dust-me-selec...


SitePoint made an extension that does this years ago. It will try and scan your whole site too, making it a bit more useful than this: http://www.sitepoint.com/dustmeselectors/


So awesome! Our project at work is quite a big web-based app and we've been developing it for the past 2 years. So you can imagine there is always things to clean up. Will definitely try this!


I've been looking for something like this, but with support for styles added using JavaScript. I have found anything yet, and it doesn't appear that this would do it either?


I started a similar project before Christmas. It has a whitelist feature, where you can list styles added using JavaScript. It may not be the perfect approach, but it's at least one way of getting around the problem.

It also supports lists of HTML and CSS files to search through. It can perform login, find duplicates, list used rules as well as unused rules, as well as count how many times each rule is matched in the markup.

Requires Node, can be installed with npm.

https://github.com/operasoftware/ucss


The only thing I could think of was to have some kind of browser extension, that works something like this:

  1. Start the extension scan

  2. Scan all external CSS currently in use (page load)

  3. Scan all inline CSS currently in use (page load)

  4. Monitor (this is the missing piece of the puzzle): Developer uses the app and extension monitors new AJAX or JavaScript added CSS rules

  5. Developer clicks a Finish and Report button:

    a) Warning for inline CSS that could be moved externally

    b) Warning for external CSS that is never used

    c) Export (per CSS file, or combined and minified) CSS files, with unused CSS removed.



Great work! Thank you. I've been wanting something like this. Would be great to see it evolve to handlebars templates someday.


Not very sure if it good tool, for sites with one css file applying to all pages.

Very possible, some css rules are only used in 1 or 2 pages.


If you CAN use it for one page at a time, excellent. If not, you have to be more careful.

Here's an example of using it on just one page at a time http://www.peterbe.com/plog/mincss-in-action


Holy crap. I had this same idea around the same time (Christmas break). Unfortunately I didn't get further than setting up the scaffolding and a name (NoClass), but I'm glad you did. Awesome and thanks!


thank you, I was looking for something like this, have to keep the label "use with caution". but great work


Yeah, unfortunately you have to know what you're doing with a tool like this. Know, as in, you need to know what's going on in your app/site.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: