Use the GZIP power!

Gzip is your friend

Short remark from the previous posts: we started at 0.2 seconds with server side and about 4 seconds with client side. Now server side is about 0.4 seconds and going to grow further (you can trace it together with client side timings in the right top corner of the every blog post, actual page load time is server + client one, the last number in the first string + value in the fourth sting). In the previous post we detected that files’ compression must save us about 50% of load time. Let’s try it!

Various gzip approaches

Gzip is the most famous and (maybe) the most mysterious client side optimization method. From year to year different issues have been being revealed about its compatibility with browsers, proxy servers, firewalls (especially corporate ones), etc. Several years ago it wasn’t used too much because of IE6 bad support (but it was fixed with SP1), and now we have a lot of other browsers (almost) all with complete gzip support.

This articles isn’t aimed to reveal all troubles behind gzip, or give you complete knowledge about other compression techniques in the world (such as deflate or bzip2). We are just trying to apply compression to our blog.

So there are several approaches to implement gzip:

  1. On raw server side (in Apache / nginx / squid / lighttpd / etc configuration). Will it work for us?
  2. On server side with PHP extensions (i.e. zlib).
  3. On server side with PHP buffers (ob_start / ob_end_clean methods).

Well, how to check if our website is gzipped or not? Generally this can be done with the mentioned tools but there are a lot of additional ways to just check if our HTML pages are compressed, for example – www.whatsmyip.org/http_compression/. Just enter your URL and get information.

Starting with .htaccess

If blog is run via Apache there is a possibility to add some rules to its configuration (on a location level, which is our document root). So we need to create a section to completely gzip all text resources. Here are a lot of useful .htaccess rules for client side optimization, we will take only mod_deflate-related ones (if your hosting provider is using mod_gzip – please use according block):

<IfModule mod_deflate.c>
	AddOutputFilterByType DEFLATE text/html
	AddOutputFilterByType DEFLATE text/xml

	AddOutputFilterByType DEFLATE image/x-icon

	AddOutputFilterByType DEFLATE text/css

	AddOutputFilterByType DEFLATE text/javascript
	AddOutputFilterByType DEFLATE application/javascript
	AddOutputFilterByType DEFLATE application/x-javascript
	AddOutputFilterByType DEFLATE text/x-js
	AddOutputFilterByType DEFLATE text/ecmascript
	AddOutputFilterByType DEFLATE application/ecmascript
	AddOutputFilterByType DEFLATE text/vbscript
	AddOutputFilterByType DEFLATE text/fluffscript

	AddOutputFilterByType DEFLATE image/svg+xml
	AddOutputFilterByType DEFLATE application/x-font-ttf
	AddOutputFilterByType DEFLATE application/x-font
	AddOutputFilterByType DEFLATE font/opentype
	AddOutputFilterByType DEFLATE font/otf
	AddOutputFilterByType DEFLATE font/ttf
	AddOutputFilterByType DEFLATE application/x-font-truetype
	AddOutputFilterByType DEFLATE application/x-font-opentype
	AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
	AddOutputFilterByType DEFLATE application/vnd.oasis.opendocument.formula-template
</IfModule>

Well actually we are going to gzip all HTML + XML files, then ICO files (yes, our favicon.ico also can be gzipped), CSS and JavaScript (well they can have a lot of various mime types) files. At the very end there are fonts according to this great post by Stoyan Stefanov. It’s a bit complicated to understand are you actually using fonts or vector graphics or not. So let’s just add these rules, they won’t increase server side load. Finally all what can be compressed must be compressed!

Also we add all rules inside IfModule condition to prevent any failure on server side. So let’s check now if this works for us – just create (or modify) .htaccess file in the root of our website with these rules. Check once more with the mentioned tool (or any browser plugin which allows to check HTTP headers, for Firefox it’s Live HTTP Headers or Firebug NET Panel):

Website response headers

Well, there is no Content-Encoding header, so this approach doesn’t work for us.

Continuing with gzip – zlib

First we need to check if our website (hosting) supports zlib. Let’s create a file named info.php with the following code

<?php phpinfo() ?>

and upload it to the root of the website. Then open it in browser. There will be complete information about current server environment; you can also check sections ‘apache’ and ‘apache2handler’ – maybe there will mod_deflate or mod_gzip extensions which should work with the previous .htaccess rules. But our main interest here is ZLIB section (which is located somewhere in the bottom of this page). It should start with heading zlib and provide information about this extension. Such as

ZLib Support enabled

Actually that’s enough to start with.

Here we can safely remove info.php file (or rename it to something unique to prevent making such secure information public) and just add to the very beginning (on the next line after <?php symbols) of our root index.php file the following strings

@ini_set('zlib.output_compression', 'On');
@ini_set('zlib.output_compression_level', '1');

What should you do if there is no zlib extension or this approach doesn’t work for you?

Compression ‘on the fly’

There is almost the last method to force gzip compression. Please note that it will work only with WordPress output (and it’s actually is used by cache plugins, so if you have enabled them – just enable gzip there, double gzipping can lead to severe troubles). We need to create a gzip filter for our content, so we need to add these lines to the root index.php file (on the next line after <?php symbols)

ob_start('webo_gzip_compression');
function webo_gzip_compression ($content) {
	$encoding = empty($_SERVER['HTTP_ACCEPT_ENCODING']) ? '' :
		$_SERVER['HTTP_ACCEPT_ENCODING'];
	$agent = empty($_SERVER["HTTP_USER_AGENT"]) ? '' :
		$_SERVER["HTTP_USER_AGENT"];
	if (!empty($content) && strpos($encoding, 'gzip') !== 'false') {
		if (!strstr($user_agent, "Opera") &&
		preg_match("/compatible; MSIE ([0-9]\.[0-9])/i", $agent, $matches)) {
			$version = floatval($matches[1]);
			if ($version < 7) {
				$content = str_repeat(" ", 2048) . "\r\n" . $content;
			}
		}
		$gzipped = @gzencode($content, 7, FORCE_GZIP);
		if (!empty($gzipped)) {
			header('Content-Encoding: gzip');
			return $gzipped;
		}
	}
	return $content;
}

Only 22 lines of code which makes your website faster. Maybe not enough, but it's only a starting point.

What to learn from this piece of magic? First we get information about User Agent (actually visitor's browser, what encoding it accepts, and if it is IE). Then we check for accepted encoding, in case of gzip just compress given content (with gzencode), set correct header (Content-Encoding) and finish. If there is IE 6- we also add 2 Kb (2048 bytes) of space to prevent a well-known bug with gzipped content in this browser. If our visitor doesn't accept gzip (i.e. it's search bot) we just output not gzipped content. That's all.

This approach is used for www.speedingupwebsite.com and it's all OK with it. Actually in IE6 it looks very weird but it can be readable, so compression works.

Conclusion

It's possible in every case to enable gzip compression, but sometimes it can be tricky for your website. There is also one more approach - static gzip - but we will cover it in the next post. Also it should be mentioned that our blog load speed hasn't changed a lot. Here is a picture from Firebug.

Firebug NET Panel

And the overall situation became even worse because we added some images and widgets to our home page, and now there is an increased amount of information. But our HTML document size is 4 Kb only. Great!

VN:F [1.8.0_1031]
Rating: 0.0/10 (0 votes cast)

Related Posts

4 RESPONSES TO Use the GZIP power!

    Leave a Reply

    MySQL queries: 85 | 0.402s
    Memory used: 14.23M
    Memory limit: 32M