How to Gzip files?

Hi,
Ive been looking at ways to make my site faster to downlaod - stuff like minifying CSS and Javascript files. One of the best ways seem to be gzipping content. It seems theres 2 compression methods with Apache - defaltion and gzip. Whats the best method? Im veering towards gzip, but thats only becasue Ive heard people talk about it. Does anyone have a simple tutorial for setting up gzip on apache? or is it better to add this cod eto each page:

<?php if (substr_count($_SERVER[‘HTTP_ACCEPT_ENCODING’], ‘gzip’)) ob_start(“ob_gzhandler”); else ob_start(); ?>

thanks

Ive just found this article which explains a slightly different way to handling gziping different file types and caching them: http://www.samaxes.com/2008/04/htaccess-gzip-and-cache-your-site-for-faster-loading-and-bandwidth-saving/

As with everything, theres seems to be many ways to skin a cat, and each one has its pros and cons… the question is which one will perform the best!

If you cannot configure the server to handle the compression of static files…and also set it up to cache those compressed files. You should not bother doing this with PHP. The gain of compression is lost if the server has to work harder compressing and running PHP on simple static files.

Ive been reading this tutorial: http://betterexplained.com/articles/how-to-optimize-your-site-with-gzip-compression/
It says “Apache actually has two compression options:mod_deflate and mod_gzip”. Anyway, Ive added the line of code…:

<?php if (substr_count($_SERVER[‘HTTP_ACCEPT_ENCODING’], ‘gzip’)) ob_start(“ob_gzhandler”); else ob_start(); ?>

…to my website and it seems to work fine. However, is the above line going to gzip all my php, css and javascript files? In the tutorial it explicitly shows how to ‘deflate’ different file types in htaccess, however Ild rather not touch the htaccess file as there is a lot going on in there and I dont want to mess anything up!

The order of files is not necessarily interchangeable, especially with JS. I would stick to serving them in the order they are requested, rather than risk sort breaking some dependencies.

Sometimes, there may be a need to have PHP variables in externalized css or js files. Due to which, PHP should process it.

It can save http requests and cause the page to load faster.

But, rather than reading and compiling each resource file on the fly,
try to make a single file with all the contents of css within it, and load it.

For example:
c.css = a.css + b+css

When a user requests, static.php?css=a.css,b.css or any other combination, you can still find out a single file (c.css) that has all the contents necessary. It is different to static.php?css=b.css,a.css.

You will first, sort the files by their names. So, the queue of b.css and a.css becomes:


$css = array();
$css[] = 'a.css';
$css[] = 'b.css';
sort($css);

$css_hash = md5(implode('', $css));

Now, send cache the css file, ‘$css_hash.css’ if exists.
This forces to reuse the cache file even if your requested css files are not in same order while you build <link> tag.

By this way, your request to static.php?css=a.css,b.css and static.php?css=b.css,a.css (by mistake, say), will still search for single cache file.

It won’t matter how many cache files you have; a total of css caches may not reach 1 MB!

Thanks guys, theres some really useful food for thought there! Ill need to take your comments and digest them further. Thanks for your input.

Unless you then cache those compressed files.
Next request, if the cached file exists, you simply serve that (and ideally, also let the file be cached in the browser cache).

bolton, normally PHP does not serve those static files (.js, .css) so they won’t be compressed with the code you have.

However I use a php script to serve those files. (I enable compression with a php.ini file — you can use your PHP code if you prefer)

Here is how it’s called:


<script type="text/javascript" src="static.php?js=myscript1.js,anotherscript.js"></script>
<link href="static.php?css=layout.css,decoration.css" type="text/css" rel="stylesheet">

It combines all the files into a single response (per type). If you have common groupings of files used on multiple pages of your site it’s a good way to reduce the number of HTTP requests.

Here is static.php. Put it in the root of your site, and it looks for the files in js and css subfolders. It assumes the CSS files refer to image paths as ‘…/images/myphoto.jpg’


<?php
/**
* Static resource combiner
* uses $_GET['js'] or $_GET['css'] array of files, (comma separated) combines them into a single response
* (different default paths)
* static.php?js=file1.js,file2.js
* static.php?css=style.css,css/green.js
* php.ini should be used to for zlib compression
*/

/*
debug mode. Set true to avoid caching 
combined files on server, and very short 
expires header. Turn on for local development
*/
$debug = false;


if(isset($_GET['js'])) {
	$dir	= 'js';		//default here, as all scripts are contained
	$id		= md5($_GET['js']);
	$cache	= 'js/_comb_' . $id . '.js';
	$list	= explode(',', $_GET['js']);
	
	header("Content-type:text/javascript");
}
else if(isset($_GET['css'])) {
	$dir	= 'css';
	$id		= md5($_GET['css']);
	$cache	= 'css/_comb_' . $id . '.css';
	$list	= explode(',', $_GET['css']);
	
	header("Content-type:text/css");
}

//Client will not recheck file for this time
if(!$debug) {
	header("Expires: " . date('r', strtotime('+30 days')));
}
else header("Expires: " . date('r', strtotime('+5 seconds')));


//Check for previously combined file
if(file_exists($cache)) {
	echo file_get_contents($cache);
	exit;
}

//Combine
$output = '';
foreach($list as $file) {
	
	# IMPORTANT SECURITY
        # no directory traversing, and only .css & .js files
	if(false !== strpos($file, '../')) continue;
	if(substr($file, -3) != '.js' AND substr($file, -4) != '.css') continue;
	
	if(file_exists($dir . '/' . $file)) {
		$output .= file_get_contents($dir . '/' . $file) . "\\r\
\\r\
";
	}
}

//CSS remove one level of ../ as doc now served from above CSS directory (where this script is)
if(isset($_GET['css'])) {
	$output = str_replace('../', '', $output);
}

//Cache the combination, reduce server work next request
if(!$debug) {
	file_put_contents($cache, $output);
}

echo $output;

If you use this you need version numbers for your static files so you can expire the client side cache. Otherwise users won’t see your changes for up to 30 days.

Deflate and Gzip are the same thing. Deflate is the raw compression algorithm.

Hi, I did see the deflate method, although all the posts Ive read have said gzip performs better.

Apache’s mod_deflate may be of some assistance here. :slight_smile: