views:

61

answers:

3

I'm currently using PHP to include multiple css (or js) files into a single file (as well as compress the content using GZIP).

E.g. the HTML page calls resources like this...

<link rel="stylesheet" href="Concat.php?filetype=css&files=stylesheet1,stylesheet2,stylesheet3"></link> <script src="Concat.php?filetype=js&files=script1,script2,script3"></script>

Example of my Concat.php file can be found here: http://dl.dropbox.com/u/3687270/Concat.php (feel free to comment on any problems with the code)

But instead of having to open up my command prompt and running YUI Compressor manually on my CSS/JS files I want the Concat.php file to handle this for at least the CSS side of things (I say CSS only because I appreciate that YUI Compressor does minification of variables and other optimisations so it isn't feasible to replicate in PHP - but that is part 2 of my question).

I know this can be done with some Regex magic and I haven't a problem doing that.

So, my question has 2 parts, which are:

1.) What is the performance implications of having the server minify using preg_replace on a CSS file (or set of CSS files that could have a few hundred lines of code per file - normally it would be a lot less but I'm thinking that if the server compresses the file then I wouldn't have to worry too much about extra whitespace in my CSS)

2.) And how can I get the JavaScript files that are concatenated via my Concat.php file run through YUI Compressor? Maybe run via the server (I have direct access to the server so I could install YUI Compressor there if necessary), but would this be a good idea? Surely optimising on the server everytime a page is requested will be slow and bad for the server + increase bandwidth etc.

The reason this has come up is that I'm constantly having to go back and make changes to existing 'compressed/minified' JS/CSS files which is a real pain because I need to grab the original source files, make changes then re-minify and upload. When really I'd rather just have to edit my files and let the server handle the minification.

Hope someone can help with this.

A: 

As suggested in the comments you could use one of the pre-built scripts for that. They make use of YUI compressor as well as other solutions even if you can't run Java on the server.

The first one was probably PHP Speedy, which still works but has been abandoned.

A new one is Minify, which offers a lot of features including general caching solution depending on the server's capabilities (APC, Memcached, File cache).

Another advantage of these projects is that your URLs won't have query strings in them (contrary to your current method), which causes troubles in a lot of browsers when it comes to caching. They also take care of gzipping and handling Expires headers for your content.

So I definitely recommend that you try out one of these projects as they offer immediate positive effects, with some simple steps of configuration.

galambalazs
Cool. Minify sounds very useful! I'm assuming it works on windows and not just apache?
Integralist
it is written in PHP so should be quite portable.
galambalazs
+1  A: 

If your webserver is Apache, you should use mod_concat and let the Apache take care of compression using gzip,

http://code.google.com/p/modconcat/

You should minify the JS just once and save the minified version on servers.

ZZ Coder
very interesting module...
Hippo
A: 

Here's how i recommend you do it:

  • Turn on GZIP for that specific folder (Web server level)
  • Use one of the tools to strip out whitespace and concat the files. This will serve as a backup for search engines/proxy users who don't have gzip enabled. You'd then cache the output of this - so the expensive regex calls aren't hit again.

The above wont be very expensive CPU wise if you configure your server correctly. The PHP overhead won't really be much - As you'll have a cached version of the CSS, ie.

-- css.php --

if (!isset($_GET['f'])) {
  exit();
}

if (file_exists('path/to/cached/css/'.md5($_GET['f'])) {
  // just include that file...
  readfile('/path/to/cached/css/'.md5($_GET['f']));
  exit();
}

$files = explode(',', $_GET['f']);

ob_start();
foreach ($files as $file)
{
  readfile($file);
}

// set a header (including the etags, future expiration dates..)
Header(....);

echo ob_get_flush(); // remove whitespace etc..


// write a new cached file
file_put_contents('/path/to/cache/'.md5($_GET['f']));

exit();

You can then do href="css.php?f=style.css,something.css,other.css" the script will then make a cache file which is the md5 of those files included.

The above example isn't complete.. it's more pseudo really.

Kieran Allen