First of all, to find out what mincss is read this blog post which explains what the heck this new Python tool is.

My personal website is an ideal candidate for using mincss because it uses an un-customized Bootstrap CSS which weighs over 80Kb (minified) and on every page hit, the rendered HTML is served directly from memcache so dynamic slowness is not a problem. With that, what I can do is run mincss just before the rendered (from Django) output HTML is stored in memcache. Also, what I can do is take ALL inline style blocks and all link tags and combine them into one big inline style block. That means that I can reduce any additional HTTP connections needed down to zero! Remember, "Minimize HTTP Requests" is the number one web performance optimization rule.

To get a preview of that, compare http://www.peterbe.com/about with http://www.peterbe.com/about3. Visually no difference. But view the source :)

Before:
Document size: Before

After:
Document size: After

Voila! One HTTP request less and 74Kb less!

Now, as if that wasn't good enough, let's now take into account that the browser won't start rendering the page until the HTML and ALL CSS is "downloaded" and parsed. Without further ado, let's look at how much faster this is now:

Before:
Waterfall view: Before
report

After:
Waterfall view: After
report

How cool is that! The "Start Render" event is fired after 0.4 seconds instead of 2 seconds!

Note how the "Content Download" isn't really changing. That's because no matter what the CSS is, there's still a tonne of images yet to download.

That example page is interesting too because it contains a piece of Javascript that is fired on the window.onload that creates little permalink links into the document and the CSS it needs is protected thanks to the /* no mincss */ trick as you can see here.

The code that actually implements mincss here is still very rough and is going to need some more polishing up until I publish it further.

Anyway, I'm really pleased with the results. I'm going to tune the implementation a bit further and eventually apply this to all pages here on my blog. Yes, I understand that the CSS, if implemented as a link, can be reused thanks to the browser's cache but visitors of my site rarely check out more than one page. In fact, the number of "pages per visit" on my blog is 1.17 according to Google Analytics. Even if this number was bigger I still think it would be a significant web performance boost.

UPDATE

Steve Souders points out a flaw in the test. See his full comment below. Basically, what appears to happen in the first report, IE8 downlads the file c98c3dfc8525.css twice even though it returns as a 200 the first time. No wonder that delays the "Start Render" time.

So, I re-ran the test with Firefox instead (still from the US East coast):

Before:
WebpageTest before (Firefox)
report

After:
WebpageTest after (Firefox)
report

That still shows a performance boost from 1.4 seconds down to 0.6 seconds when run using Firefox.

Perhaps it's a bug in Webpagetest or perhaps it's simply how IE8 works. In a sense it "simulates" the advantages of reducing the dependency on extra HTTP requests.

Rene Dudfield - 22 January 2013 [«« Reply to this]
Very cool! <3 it :)

There'd be a much bigger audience for it if it came as a script, rather than tied up in Django stuff. Well, at least then I could use it ;)

Have you tried it on other frameworks, or websites apart from bootstrap ones?
Peter Bengtsson - 22 January 2013 [«« Reply to this]
mincss has nothing to do with Django. Did you see this? http://www.peterbe.com/plog/mincss

I have, for example, not used it on my one-page-tonnes-of-javascript *app* http://aroundtheworldgame.com because it's just too much Javascript dependent.
Rene Dudfield - 22 January 2013 [«« Reply to this]
Aha! No, I missed that link. Brilliant :)
Joe Ciskey - 22 January 2013 [«« Reply to this]
The obvious feature to add is taking a list of pages, applying the script to each of them, and then aggregating the entire result so that you have a site-wide CSS file that can be cached by browsers. I might just fork this and give it a try.
Peter Bengtsson - 22 January 2013 [«« Reply to this]
It already exists. The API is built such that you feed it URLs till your done then call the `.process()` method to start the calculation. For example:

  >>> from mincss.processor import Processor
  >>> p = Processor()
  >>> p.process_url('http://example.com/page1.html')
  >>> p.process_url('http://example.com/page2.html')
  >>> p.process()

However, if you do that, the `p.inlines` will be confusing since you won't know which URL it came from. There's a shortcut to when you just have 1 single URL to worry about and that's to use `.process()` directly:

  >>> from mincss.processor import Processor
  >>> p = Processor()
  >>> p.process('http://example.com/page.html')

Or you can actually do this too:

  >>> from mincss.processor import Processor
  >>> p = Processor()
  >>> p.process('http://example.com/page1.html', 'http://example.com/page2.html')

Messing around with doing one page at a time and using inline is more advanced and perhaps something just for those who want the absolutely fastest.
Steve Souders - 23 January 2013 [«« Reply to this]
Hi, Peter. It's fun to read about how mincss is making sites faster. I have one issue with your results, however. You mention how the page starts rendering much sooner. If we look at the "before" results ( http://www.webpagetest.org/result/130121_H_1MQ/1/details/ ) we see that rendering is blocked waiting for c98c3dfc8525.css. The weird thing is we can see that c98c3dfc8525.css is downloaded TWICE (see requests #2 & #12). It would be great if you could figure out why this happened (IE8 anomaly?) and re-run to get more comparable results.
Peter Bengtsson - 23 January 2013 [«« Reply to this]
It appears to respond with a 200 the first time so I honestly don't know what's going on.

I'll re-run the tests with a sane browser and see if it's reproduce-able.
Peter Bengtsson - 23 January 2013 [«« Reply to this]
Updated the blog post.


Your email will never ever be published