Three Ways to Speed up Your Site with PHP

3 Ways to Speed up Your Site with PHP

These days, with broadband connections the norm, we don’t need to worry as much about internet speeds or the filesize of our pages. However, that’s not to say that we still shouldn’t do so. If you wish to reduce the load times on your server, decrease the number of HTTP requests, and go that extra bit for your visitors, there are a few techniques that you can use. This tutorial covers a number of PHP tricks, including caching and compression.

1. CSS Amalgamation with PHP

As web developers, we often split up our CSS between several separate files to keep a logical separation and to make modifications easier. However, this increases the number of requests to the server, resulting in a slower page load. Using some PHP we can have the best of both worlds; keeping multiple files on our end, and using one request to retrieve all of them.

Preparation

Before we can optimize CSS files, we will need some CSS to work with! So let’s make three files and put some CSS in them.

	// main.css
	// Just some sample CSS

	body {
		width: 800px;
		margin: 0 auto;
		color: grey;
	}

	#wrapper {
		margin-top: 30px;
		background: url(../images/cats.png);
	}
	// typography.css
	// Just some sample CSS

	body {
		font-family: Arial, san-serif;
		font-weight: bold;
	}

	strong {
		font-size: 120%;
	}
	// forms.css
	// Just some sample CSS

	form {
		position: relative;
		top: 400px;
		z-index: 99;
	}

	input {
		height: 50px;
		width: 400px;
	}

The PHP

We need to get the contents of these files and append them to each other in a specified order. So our script has to receive the names of the CSS files via URL parameters, open all the files and put them together. An explanation of the code follows.

<?php
//Lets define some useful variables
// --- NOTE: PATHS NEED TRAILING SLASH ---
$cssPath = './css/';

if (isset($_GET['q'])) {
	$files = $_GET['q'];
	// Got the array of files!

	//Lets just make sure that the files don't contain any nasty characters.
	foreach ($files as $key => $file) {
		$files[$key] = str_replace(array('/', '\\', '.'), '', $file);
	}

	$cssData = '';
	foreach ($files as $file) {
		$cssFileName = $cssPath . $file . '.css';
		$fileHandle = fopen($cssFileName, 'r');
		$cssData .= "\n" . fread($fileHandle, filesize($cssFileName));
		fclose($fileHandle);
	}
}

// Tell the browser that we have a CSS file and send the data.
header("Content-type: text/css");
if (isset($cssData)) {
	echo $cssData;
	echo "\n\n// Generated: " . date("r");
} else {
	echo "// Files not avalable or no files specified.";
}
?>

Breaking it Down

It looks quite complicated, but stick with me, it’s really pretty simple.

<?php
//Lets define some usefull variables
// --- NOTE: PATHS NEED TRAILING SLASH ---
$cssPath = './css/';

if (isset($_GET['q'])) {
	$files = $_GET['q'];
	// Got the array of files!

	//Lets just make sure that the files don't contain any nasty charactors.
	foreach ($files as $key => $file) {
		$files[$key] = str_replace(array('/', '\\', '.'), '', $file);
	}

This chunk of code sets the path for the CSS folder and checks that we have been sent some files to work with. The CSS path needs to have trailing slashes otherwise we will find ourselves with bucket-loads of errors. If we wanted, we could check automatically for a slash and add it if required. However, for the sake of simplicity I omitted that behavior.

Next we check each filename and remove any full stops and/or slashes. This prevents people from navigating the filesystem by passing filenames such as ‘../../secret/file’.

	$cssData = '';
	foreach ($files as $file) {
		$cssFileName = $cssPath . $file . '.css';
		$fileHandle = fopen($cssFileName, 'r');
		$cssData .= "\n" . fread($fileHandle, filesize($cssFileName));
		fclose($fileHandle);
	}
}

Now we have to build our CSS data from the individual files. To do this, we loop through the files array with foreach, open each file and append the contents onto our data. The “\n” simply adds a new line character to keep things nice and tidy. The filesize() function is used to find the length of the file so that we can tell fread() how much we want (the entire file).

// Tell the browser that we have a CSS file and send the data.
header("Content-type: text/css");
if (isset($cssData)) {
	echo $cssData;
	echo "\n\n// Generated: " . date("r");
} else {
	echo "// Files not avalable or no files specified.";
}
?>

The last bit of the script is to send the CSS data to the browser. This means we have to tell PHP that we are sending CSS data, and that it should inform the browser. We do this with the header function, setting the content type to ‘text/css’. Then we send the CSS to the client. We first check if there is any CSS data to send. If there isn’t, then this means that no names of CSS files were sent. If this is the case we simply reply with a CSS comment saying so. If, however, we do have some data to send, then we send that and add a message detailing when it was generated. If you wanted to, for example, add some copyright information to all your CSS in one go, then this would be an ideal place.

Putting it to the Test

Okay, now it’s time to test the script; we need to first build a directory structure and then place our script and CSS files. Have a look at the image below and try to replicate that structure. If you want something different, don’t forget to change the paths to reflect those changes.

Once everything is in the right place, we can test our script. The directory structure will have to be placed in the ‘htdocs’ or ‘www’ folder of a webserver with PHP (pretty much any webserver these days). Navigate to the index.php file. You should be greeted by a single comment: ‘Files not available or no files specified’. This means that we have not given any files for it to pull together. However, the good news is that this is a valid CSS comment and won’t cause any problems.

Let’s give something a little trickier a go; type in ‘index.php?q[]=main’, you should get the CSS from you main.css file and a notice at the bottom.

If we want to pull multiple files together (as this was really the entire point of the script) we can send this request: ‘index.php?q[]=main&q[]=forms’. As you can see we can repeat ‘q[]=’ as many times as we want because it is adding each value to an array. You could potentially add 50 CSS files together if you wanted using this script.

Concluding

Using this method can be very useful, and can provide benefits such as being able to have a default style sheet for every page and and an extra CSS file for pages with forms. It’s also easy to implement if you’re already using some sort of CSS processing with PHP. If you want, you can even rename index.php to index.css as long as you set up .htaccess to treat CSS files as PHP.

You might notice that I’m treating different orders of CSS files as different. This is because you may wish to have one stylesheet override another and therefore the order of the files is important. If this isn’t a problem for you, you may wish to perform a sorting function on the files array before processing.

Just a word of caution; if you place the index.php file in any folder other than the one that contains the CSS then you have to write your relative background image paths as if index.php was your stylesheet. This is because that’s what the browser thinks it is. Alternatively, you could add some code to rewrite these URLs, however, that is beyond the scope of this tutorial.

2. Stripping Whitespace from your HTML and CSS

Many of us use large amounts of whitespace when writing code. The good news is that whitespace in PHP doesn’t actually get sent to the browser. However, it does in HTML.

Browsers tend to only display one space no matter how many tabs you use in your code. This means that there is some wasted bandwidth. However, with some simple PHP we can remove this bandwidth leeching whitespace.

Preparation

Once again, we will need some raw data to work with; so copy the following example HTML and CSS code. Save the following into a .htm and a .css file in a folder within your server’s webroot directory.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
	<head>
		<title>Hey a Page!</title>
		<link rel="stylesheet" href="./css.css" type="text/css">
	</head>
	<body id="homepage">
		<div id="wrapper">
			<div id="header">
				<h1>Kittens for sale!</h1>
				<div>
					There   are      lots      of spaces here! But we need to get    rid   of  them!
				</div>
			</div>
			<div id="mainbody">
				Lorem Ipsum dol...
			</div>
		</div>
	</body>
</html>
body {
	min-height: 800px;
	background: black;
	font-size: 18px;
}

#wrapper {
	width: 960px;
	margin: 20px auto;
	padding: 15px;
}

#header h1 {
	text-indent: -99999em;
	background: url(../images/header.png);
	display: block;
	width: 100%;
	height: 48px;
}

#mainbody {
	font-weight: bold;
}

The PHP

One of the advantages of this method is that the same script will work with both HTML and CSS. Our script has to accept a filename as part of the request. Once the file has been loaded, it has to strip all whitespace down to just one space character. This is because we don’t want to remove all the spaces between words!

Once again, ther’s a bunch of PHP here, but I will go through it carefully with you.

<?php
$fileDirectory = '';
$file = $_GET['q'];
$nameExplode = explode('.', $file);
$ext = $nameExplode[1];
$fileName = $fileDirectory . $file;
if ($ext != 'css' AND $ext != 'htm' AND $ext != 'html') {
	//Check for evil people...
	die('Hackers...!');
} else {
	//Lets get down to business
	$handle = fopen($fileName, 'r');
	$fileData = fread($handle, filesize($fileName));
	//Now for some regex wizzardry!
	$newData = preg_replace('/\s+/', ' ', $fileData);
	fclose($handle);
	//Time to output the data.
	if ($ext == 'css') {
		header("Content-type: text/css");
	}
	echo $newData;
}
?>

Having a Closer Look

This one isn’t so tricky, but we will still break it up and make sure we understand what is going on.

We are getting the filename via a parameter passed with the GET request and checking to make sure that it is an allowed filetype. Then we proceed to fetch the data and process it to remove excess whitespace. This method is relatively primitive and won’t remove all unnecessary whitespace, but it will deal with most of it in only a few lines of code!

<?php
$fileDirectory = '';
$file = $_GET['q'];
$nameExplode = explode('.', $file);
$ext = $nameExplode[1];
$fileName = $fileDirectory . $file;

This snippet just sets some variables. Once again, we are passing our data through ‘q’ as it is nice and short. This also gives us a place to define our directory for files and extract the file extension. The explode() function rips the filename up whenever it sees a ‘.’ and puts the bits into an array.

if ($ext != 'css' AND $ext != 'htm' AND $ext != 'html') {
	//Check for evil people...
	die('Hackers...!');
} else {

Here we’re checking to make sure that the file is either CSS or HTML. If it was something else we might find ourselves giving hackers a hole into our site like showing them settings.php! So after giving the hackers the flick we can move on to processing our data!

	//Lets get down to business
	$handle = fopen($fileName, 'r');
	$fileData = fread($handle, filesize($fileName));
	//Now for some regex wizzardry!
	$newData = preg_replace('/\s+/', ' ', $fileData);
	fclose($handle);
	//Time to output the data.
	if ($ext == 'css') {
		header("Content-type: text/css");
	}
	echo $newData;
}
?>

Now for the main attraction; all we are really doing here is opening the file and reading it – like we did in the first script – and then ripping out as much whitespace as possible. This is achieved through a relatively simple regular expression that searches through the file for any spaces, tabs or newlines and then replaces them with a single space.

Lastly we send back the data, setting the required headers if we are dealing with CSS.

But Does it Work?

If you go into your browser and navigate to ‘index.php?q=css.css’ we should see one line of CSS across the page. This shows that everything is fine! We can also see the same effect on the source code for the html example. In fact in that small example, we reduced a 314 character CSS file down to 277 characters and a 528 character html file down to 448 characters. Not bad for 15 lines of code.

Conclusion

So that’s a good example of how we can do quite a lot with very little work. If you have a look at the source of pages like Google you will find that they have almost no whitespace because, when you receive millions of requests, a few extra kilobytes per request really adds up. Unfortunately, most of us aren’t that lucky!

3. Caching in your PHP Scripts

In this part, I will show you how to ‘retrofit’ caching into your scripts using the above script as an example. The aim is to speed things up by not having to regenerate the data every time someone requests a file. Generating the content every request is just a waste, especially on static data such as our CSS.

To add caching we need to add three things to our script. Firstly, we have to collect the data input to the script and generate a filename unique to that set of inputs. Secondly, we have to look for a cache file and see if it is sufficiently recent. Lastly, we have to either use the cached copy or generate new content and cache it for next time.

Breaking the Flow

This part of the process really depends on the individual script, however I will show where I am going to break the flow of this script for the caching.

<?php
$fileDirectory = '';
$file = $_GET['q'];
$nameExplode = explode('.', $file);
$ext = $nameExplode[1];
$fileName = $fileDirectory . $file;

//-- WE HAVE ENOUGH DATA TO GENERATE A CACHE FILE NAME HERE --

if ($ext != 'css' AND $ext != 'htm' AND $ext != 'html') {
	//Check for evil people...
	die('Hackers...!');
} else {

	//-- WE CAN INTERCEPT AND CHECH FOR THE CACHED VERSION HERE --

	//Lets get down to business
	$handle = fopen($fileName, 'r');
	$fileData = fread($handle, filesize($fileName));
	//Now for some regex wizardry!
	$newData = preg_replace('/\s+/', ' ', $fileData);
	fclose($handle);
	//Time to output the data.

	//-- NOW WE CAN STORE THE NEW DATA IF REQUIRED AND OUTPUT THE DATA --

	if ($ext == 'css') {
		header("Content-type: text/css");
	}
	echo $newData;
}
?>

Putting it into Action

We will now actually write the code for caching into this script. I will first show the script completed and then go through each piece.

<?php
$fileDirectory = '';
$file = $_GET['q'];
$nameExplode = explode('.', $file);
$ext = $nameExplode[1];
$fileName = $fileDirectory . $file;
$cacheName = './cache/' . $nameExplode[0] . $nameExplode[1] . '.tmp';
if ($ext != 'css' AND $ext != 'htm' AND $ext != 'html') {
	//Check for evil people...
	print_r($ext);
	die('Hackers...!');
} else {
	if (file_exists($cacheName) AND filemtime($cacheName) > (time() - 86400)) {
		$cacheHandle = fopen($cacheName, 'r');
		$newData = fread($cacheHandle, filesize($cacheName));
		fclose($cacheHandle);
		$isCached = TRUE;
	} else {
		//Lets get down to business
		$handle = fopen($fileName, 'r');
		$fileData = fread($handle, filesize($fileName));
		//Now for some regex wizardry!
		$newData = preg_replace('/\s+/', ' ', $fileData);
		fclose($handle);
		//Lets cache!
		$cacheHandle = fopen($cacheName, 'w+');
		fwrite($cacheHandle, $newData);
		fclose($cacheHandle);
		$isCached = FALSE;
	}
	//Time to output the data.
	if ($ext == 'css') {
		header("Content-type: text/css");
		if ($isCached) {
			echo "// Retrieved from cache file. \n";
		}
	} else {
		if ($isCached) {
			echo '<!-- Retrieved from cache file. -->';
		}
	}
	echo $newData;

}
?>

The Explanation

This one’s a bit trickier and a little more likely to leave you scratching you head. But don’t worry, not much has changed and we will go through each section. An extra feature we have included is the refreshing of the cache every 24 hours. This is handy so if you change anything, you can either wait 24 hours or simply empty the cache directory. If you want a different refresh interval just calculate it in seconds.

$cacheName = './cache/' . $nameExplode[0] . $nameExplode[1] . '.tmp';

This bit of code just gets the file’s name and extension, glues them together and adds the cache directory and the appropriate ‘.tmp’ extension.

	if (file_exists($cacheName) AND filemtime($cacheName) > (time() - 86400)) {
		$cacheHandle = fopen($cacheName, 'r');
		$newData = fread($cacheHandle, filesize($cacheName));
		fclose($cacheHandle);
		$isCached = TRUE;
	} else {

Here we’re checking if we have a cache file saved and if the cache file was created within 24 hours. If both these conditions are met then we open the file and extract its contents to substitute for the scripts output. We also set $isCached to true so we can output some messages at the end.

		//Lets cache!
		$cacheHandle = fopen($cacheName, 'w+');
		fwrite($cacheHandle, $newData);
		fclose($cacheHandle);
		$isCache = FALSE;
	}

Now we are caching the output of the script for us to use in later requests. We simply open a file in write mode, dump our data into it and then close it. Strictly you don’t have to close files in PHP but it’s considered a good practise so I have done it here.


	//Time to output the data.
	if ($ext == 'css') {
		header("Content-type: text/css");
		if ($isCached) {
			echo "// Retrieved from cache file. \n";
		}
	} else {
		if ($isCached) {
			echo '<!-- Retrieved from cache file. -->';
		}
	}

This is another part of the script that was modified a little so that we can offer some feedback through the browser. If the file was retrieved from the cache we can add a message to the script’s output. Notice that the message for CSS scripts has ‘\n’ at the end. This is because the characters ‘//’ comment our entire line and ‘\n’ pushes everything else onto another line. If you want to disable the messages all you have to do is comment out the line ‘$isCached = TRUE;’.

Giving it a Whirl

If we use our script again, we will notice no change until we refresh a second time when we will see a message saying that the file was retrieved from cache. Sweet success! This caching setup can also be applied to the first script with little modification, however, that is left as an exercise for the reader.

Concluding

Being able to quickly add simple but effective caching to any script that you are working on is an extremely useful skill. It just adds that extra bit to the script, reducing the load on your server and speeding up the site for users. Now that’s win-win!

Summing it Up

In this tutorial I have shown you a few handy but simple ways to speed up your site with a dash of PHP. I really hope that you find them useful and that you can apply them to a project in the future. How do you improve your site’s performance?


Add Comment

Discussion 127 Comments

Comment Page 1 of 21 2
  1. Joel Acevedo says:

    Thanks for the article.

  2. Meshach says:

    Thanks for the tips, I don’t know how practical use this would be though…

  3. Zac says:

    Cool, thanks for the ideas. How much time would this really save on load time? CSS is just text, after all.

    • anonymous cowherd says:

      As far as stripping whitespace, no benefit whatsoever if you have gzip compression enabled on your webserver, as that will already make the actual transferred data much smaller than the size of the html and css files themselves.

  4. Eire32 says:

    Umm some interesting. But I’d be sceptical on by caching this is really a necessity. Unless the cache limit was set high enough I would think that creating and serving this cached version could take more resources than your saving. Optimization is always such a balance, so I’m sure this might be the balance people are looking for but I’d think you’d need to do some timer testing to see if these actually helps or not.The key concept is about saving money on bandwidth, but are you going need to spend more money on a better server to handle all this caching. Good article none the less easy to follow.

    • chris says:

      I think what he meant by caching is to store a html (static) copy of the page, specifically if it access a database, and serve that copy to the user rather than accessing the database and processing the page for every request. I don’t think he really meant caching in the sense as storing it in memory on the server. Though if that is what he meant you would be correct.

    • Thomas Drake-Brockman says:
      Author

      No, it wasn’t my intention to suggest memory caching. I meant file caching as your can see in the example.

  5. genial! a aplicarlo!

    • Thomas Drake-Brockman says:
      Author

      I don’t understand (what I assume is) Spanish. But thanks! =P

      • IRV says:

        He said :”great!, let’s use it!”

        Thanks for the article, very interesting. I don’t think I will use these tips for a while since I’m not working on any project that requires them (in a small web project does not worth the effort to make a whole caching system), but I’ll try and see how they work.

  6. Good advice but wouldn’t it be more beneficial to remove the whitespace prior to uploading it live instead of using PHP to strip it out?

    • anonymous cowherd says:

      perhaps, but better still is to enable gzip compression in your webserver, to compare try gzipping your html and comparing sizes to a version with the extraneous whitespace stripped out.

    • Thomas Drake-Brockman says:
      Author

      Yes, that is a perfectly valid way to do it, however, that adds another step to your deployment process. Also this is a PHP tut, mostly for education in PHP.

  7. James says:

    Be very careful with compressing (removing spaces from) HTML files; sometimes spaces need to be retained; for example, within [pre/] tags… And what about inline [script/] elements? – you’re going to replace all the spaces there too…

    • Thomas Drake-Brockman says:
      Author

      The first version of the script took this into account but for this audience a certain amount of simplicity is required.

  8. aeiou says:

    LOL what aload of garbage.

    You do realise serving css through php is going to have _severe_ performance degradations?

    Also have you not heard of GZIP? apache should be gziping your static files and guess what…. gzip is HIGHLY optimized for encoding files, especially whitespace runs…

    Doing this to increase performance just stinks of not having a clue what you are doing

    • Johan says:

      I agree, totally!

      fopen()/fread(), including filesize() to read local css files, file_get_contents() would be simpler and a little bit faster and include/require even faster and simpler because they are language constructs and then using output buffering.

      Stripping whitespace by preg_replace() all over the file can also give more of a performance penalty than leaving those bytes of whitespace in the file, and as said before, running gzip on the contents would be a better alternative.

      The caching part also suffers from the fopen/fread part…

      Caching with include/require, output buffering and gzip compression should cover all of this in 50% of the code and be far more efficient.

  9. Mathew says:

    I require Benchmarks to believe what’s been said in this article.

    • Thomas Drake-Brockman says:
      Author

      I provided a few example of the filesize saved. Feel free to test to check if this is viable for you!

    • Patrick says:

      äh, Mathew… That are facts, there are no needs for benchmarks.

      1 request is even better than 3. if you have 10 site requests per Second you save 20 not needed file-requests, serverload and bandwidth-usage sinks.

      compress css-files – what is better? larger or smaller files?

      caching – best way to decrease the database load. fewer database requests = saved computing time = more user can request your site.

      that are logical facts, no fantasy.

      • anonymous cowherd says:

        number of requests – yes, you have something there, although that’s not usually a bottleneck…

        stripping whitespace – stripping whitespace is not compressing a file, on a properly configured web server, your tip is worse than useless, putting extra work on the developer when gzip compression would save more bandwidth by compressing the plaintext css and html files before transferring them.

        caching – yes, caching is the only really worthwhile tip given here

        Thems the logical facts, no fantasies here…

      • Thomas says:
        Author

        Yes, especially as browsers (usually) can only process the downloading of two files at a time!

  10. Developnew says:

    thanks for tips..

  11. I very much like the idea of combining my CSS files into one file, but in my experience, if I am also using gzip compression (which I am), then IE6 gets really buggy in terms of if the page will even load at all. IE6 does not handle compressed CSS files well (or at all). I know everyone wants to pretend IE6 doesn’t exist, but depending on your target audience, IE6 users can still be a large percentage of your site visitors.

    Then about caching. This is great for semi-static content, but if you use any kind of authentication system that outputs a logout link, and perhaps the currently logged in user’s username, then unless I’m just not being creative enough, you can’t cache anything.

    I’d love to know some solutions to these problems I have described. I’m always looking to speed up my website!

    • Thomas Drake-Brockman says:
      Author

      You can always cache only certain parts of your site, more of a job but certainly possible!

      Also these techniques shouldn’t affect IE6 at all.

  12. Michael says:

    thx for your tut..

    i suggested an XML TUT for a while.. no one wants to know this?
    please take a look at the suggestions..

  13. additional knowledge… thanks keep on shinning!

  14. Jakub says:

    This code is potentially dangerous. What about file.css.php ? I think this is not safe at all and requires more testing before output

  15. Dean says:

    Nice tutorial!
    It’s just so much easier to combine all the CSS files into one. No need to list multiple CSS files in the header = me happy :)
    Also… caching = brilliant :D
    Thanks!

  16. Excellent tip and code! A useful code, Thanks!

  17. Chillibeans says:

    I thought half the idea off having a seperate stylesheet was so the browser didn’t have to download the styles everytime it loaded a new page. With the method you mentioned above it looks as though you would need to send the styles with the html everytime.

  18. Diego SA says:

    Yeah, let’s get everything speeded up!
    Man, what a great steps! Brilliant!
    Thanks a lot!

  19. I really liked this post, well done!

  20. iceman says:

    what is the firefox theme you are using

  21. Rob says:

    Wow, these have to be the 3 worst tips I have ever come across. I actually thought this post was from 1998 until I read the date.

  22. Diego SA says:

    There’s something I don’t get. How is these “/\s+/” made? I mean, what is the name of this thing? How is it defined?
    Once I was edting a Javascript and a huge thing like this pop up in front of my eyes and I said “WTF????”
    What I realized is this thing chooses specifics characters to be replaced (yeas, it was being used inside a “replace”). How this thing is written?
    OK, you guys got it right? I still learning it. Could you guys explain me? Thanks!

  23. Tomin says:

    Nice article=)

    But if you have multiple css files, can’t you just link to one in the html, and use @import in the css file?

    Also, is there a way to do the same with javascript? Instead of linking to multiple scripts, it would be easier to use php to get all, and reduse the number of http requests?

  24. You’d be better off putting any file combination and minification in a build script when you send the file to the server. That way this only ever happens once.

    Plus, it’s better to have your static files (css, javascript, images) on an actual static box where you don’t boot up PHP or any other scripting language just to serve files.

    And as the anonymous guy is saying, gzip will give you huge benefits! All you gotta do it turn it on, and the benefits are automatic.

  25. Csaba says:

    Interesting tips, however I think it can slow down an execution of PHP scripts. Especialy preg_replace function is one of the slowest PHP functions.

    So I think the big power of this technique needs caching + gzip compression.
    With both of these it can be powerful and nice technique.

  26. Michael says:

    Great tutorial! I do like the css compression. It’ll save a few hits to the server…especially for sites that have lots of them. Great job!

  27. Thanks :)

    twitter.com/sonergonul
    friendfeed.com/sonergonul

  28. blazedd says:

    NICE! I made a tutorial talking about this of striping whitespace and combining files with php.

  29. Aaron M. says:

    This is a good tutorial. If you need something more advanced and flexible, check out http://code.google.com/p/minify . I have been using it for a couple of years now and it works extremely well.

  30. James Hogan says:

    This article shows just how powerfully simple php is. nice. I’m going to try to implement css file combining in java for my next project, thanks for the inspiration,

  31. RJQ says:

    Actually, double-slash comments in CSS won’t work.

    CSS comments are like so: /* comment */

    http://www.google.com/search?q=css+comments

  32. EllisGL says:

    In the reduction of white space in HTML, what about the PRE tags?

    • I think for a simple example Thomas left out writing some more complex rules to detect certain tags that need white space to perform properly. So if you were to extend his script your could get the PHP to skip the compression on PRE tags and carry on compressing the rest of the doc’.

      • Thomas says:
        Author

        Exactly, with tutorials somethimes it comes down to getting the idea done as simply as possible.

  33. rap says:

    Nice tips! I will definitely try your CSS Amalgamation. BTW, I’m using PEAR to cache my pages. Is that okay?

  34. Chris says:

    So, this will make the site load a little faster for your users (maybe) but slow down the server.

    Echoing what is said above, minify it before uploading or gzip it on your server.

  35. Thomas Drake-Brockman says:
    Author

    Thanks guys for all your nice comments!

    On the issue of my scripts being slow:

    This is but one solution, not the be and end all!
    Feel free to use whatever rocks your boat

  36. ayeo says:

    Hi!

    What for merge css files? The browser get it only once. In my opinion it dosen’t make any noticeable diffrence.

  37. Dzinepress says:

    you always post latest trend and helping stuff. this is really appreciated. thanks

  38. begs says:

    At Point 1: Why would you have to load the CSS files through URL requests?
    Wouldn’t it be easier to simply load it via PHP calls, or better: the PHP glob() function?

  39. using the method described here will cause the browser to reload the whole CSS much too often as PHP usually turns off any client side caching. Before this becomes useful, you will have to implement the client side caching facilities like If-Modified-Since, ETag / If-None-Match and maybe Expires.

  40. SwedishChef says:

    Hey, nice article.I had some thoughts when i read it.

    1) Should this be used on a live server, you probably would like to escape the _GET a wee bit more.
    2) Getting the file extension via explode is fast, but not the best way. t’ll break if there are more than two or more periods in the filename. Like my.fabulous.css. With the explode script it would return “fabulous” as extension. Lookup the function basename or maybe use something like return substr($file , strrpos($file , ‘.’) +1);

  41. Dave says:

    Nice tut, but wouldnt it be better to also minify the css?

  42. I like the techniques used but for example, the CSS grouping, personally I’d just keep it all in one file to start with. I used to split them up but now have reverted to just have commented sections to split them up. For me it’s another unnecessary complication to have to group them with PHP.

    The web should be getting simpler, we shouldn’t be having to create work arounds. Ultimately we won’t have to worry about these things as we move closer to things like HTML and CSS3.

    I’m not saying your tips are bad, they’re well written and might be worth considering for large applications or put into practice in a different way.

    I love reading PHP bits like this regardless, so lets have some more. :D

  43. Andy Gongea says:

    Sorry but I disagree. I don’t need a PHP script in order to minimize my CSS file. It is enough to use a CSS compressor and upload my CSS. And I will keep a version on my PC for development – the compressed one goes into production.

  44. Water Tanks says:

    Cool I am trying To learn CSS and it looks I need to learn Php too,
    thanks for the help Hope It improves The speed which is noticable

  45. James says:

    Also, be VERY careful with CSS amalgamation. The order of CSS decelerations shouldn’t be overlooked. Things like selector-specificity have to be considered.

  46. bart says:

    You can do more. This is how to do it with TYPO3 http://techblog.evo.pl/en/2009/03/21/how-to-boost-speed-up-your-typo3-website-with-nginx/ but idea is common for any application. You can use memcache without nginx but these two application gives awesome speed ;)

  47. John Girvin says:

    Thanks for the article. Have you seen Minify on Google Code? It does much of what you describe already:

    “Minify is a PHP5 app that can combine multiple CSS or Javascript files, compress their contents (i.e. removal of unnecessary whitespace/comments), and serve the results with HTTP encoding (gzip/deflate) and headers that allow optimal client-side caching.”

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

    As other commenters have said, the best approach is to minify during a build process prior to deployment, but something like Minify can be useful if your workflow doesn’t include that kind of step.

  48. Patrick says:

    So. Nice hints to speed up a website.

    But: In case of css – you sometime needs special IE css hacks – they are not considered here. I think its important to mention that. Oh, and: Why dont you use file_get_contents() ? Would be faster.

    Caching:
    What about APC (Alternative PHP Cache) or Memcached? They’re really good tools for dynamic caching – its faster than filecaching.

    What about eAccelerator? Okay, it has nothing to do with PHP coding, but its a good ay to speed up PHP Scripts softwaresided.

    • Thomas says:
      Author

      I don’t claim to know every function in PHP, that’s the best way to do it I know. If you have a better way feel free to use it.

  49. Mediashake says:

    Yay!! Genius!
    I needed this for a part of my project :D
    Thanks a load!

Comment Page 1 of 21 2

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.