How To: Optimize Your CSS Even More

Over the summer I wrote a post called 5 Ways to Speed Up Your Site that went through some basic tips for getting your site to load faster. I mentioned enabling gzip compression in WordPress and using services that remove the whitespace from your CSS, effectively "compressing" it. Now, I'll go a bit more in-depth with a simple, yet powerful, PHP method of compressing your CSS.

What We're Doing

The WordPress method of compression gzip's your site's markup, but it doesn't go so far as compressing your linked stylesheets. To get the benefit of a compressed CSS file (or more, if you have several), I'm going to go a bit deeper by adding this compression directly on each CSS file.

Things You Should Know

All forms of compression, including this PHP method, will utilize a tad of your server's CPU to compress data. For most this is negligible, but if you know that you are on a flaky, shared-server-using webhost you might rethink using compression on your site. But I mean, it would have to be a flaky webhost.. a 5/year host as from what I've seen most decent servers can handle compression no problem.

Also, not every browser supports gzip compression. However, you'd have to be running a very old browser for that case to appear. Kyle Neath tells me that IE 4+, Netscape 4+, Opera 5+ and all versions of Safari and Firefox support gzip compression, so I would say that it is very safe to go ahead with using gzip compression in terms of compatibility.

Edit: The method of gzip compression I will be pursuing utilizes ob_gzhandler which is smart about compressing data..

Before ob_gzhandler() actually sends compressed data, it determines what type of content encoding the browser will accept ("gzip", "deflate" or none at all) and will return its output accordingly. All browsers are supported since it's up to the browser to send the correct header saying that it accepts compressed web pages.

Gains

With compression you save bandwidth by having smaller file sizes. For example, my already whitespace-free CSS file was around 9kB before compression. After, it weighed in at only 2.4kB. While that is a great compression rate, let me show you the difference on your typical CSS file. Using digg's global CSS file as an example - before compression the CSS was 26.3kB and after compression it was only 6kB. Amazing stuff.

Okay Already, Show Me How!

First off, make a copy of your current CSS file and add the suffix ".php" to the file name. If your CSS file was named style.css your new file would be named style.css.php (don't include this period to the right > ).

Next, update your CSS link to reflect this change. Note: Don't copy and paste the any of the code below - my blog displays quotes as smart quotes instead of regular ones and this will mess it up. Just type it as you see it.

Before <link rel="stylesheet" type="text/css" media="screen" href="/style.css"/>

After <link rel="stylesheet" type="text/css" media="screen" href="/style.css.php"/>

Now to the real part. Open up your style.css.php, or whatever you named it, file and add the following snippet of PHP to the very top:

<?php if(extension_loaded('zlib')){ob_start('ob_gzhandler');} header("Content-type: text/css"); ?>

Then, add the next line to the very bottom and save the file.

<?php if(extension_loaded('zlib')){ob_end_flush();}?>

That's it! Refresh your site and check it out.

How It Works

The first part of the PHP code checks to see if your server's PHP installation supports zlib, which is required for the gzip compression we are trying to attain. If that's all fine and dandy, output buffering begins processing with ob_gzhandler, which creates gz-encoded data if supported by the user's browser. The last line stops the output buffering and sends the contents of the buffer to the user. It is debated whether or not ob_end_flush() is actually required since it is apparently called automatically by PHP at the end of the script execution, however I kept it in there for good measure.

If you did just the output buffering, this method wouldn't work since the browser doesn't know how to parse it. That's why the header of content-type text/css must be sent out.

What Do You Think?

As of now, this blog's homepage comes in at 27.6kB from its already lightweight 34kB. If I didn't have those three sponsor graphics in my sidebar, it would only be about 15kB.

After you have dealt with compression and saving images for the web, the next thing would be optimizing database queries.. but that's another article or series of articles in itself.

What do you do to ensure that your site runs and loads as fast as it can?