no mod_deflate? use mod_rewrite!
Sadly, the shared hosting service for my web site does not support mod_deflate in its Apache installation. There are various resources on the web that deal with this in one way or another, but they all talk about the drawbacks of shutting out certain clients or presenting errror pages to some of them. Well, if you cannot get on-the-fly compression, there is at least the drawback of having to compress all your pages statically before hand, thus providing duplicate files for each. But that is actually a good thing - it serves even faster that way because it does not have to compress anything while it is serving the content. So you put in a little more work on site updates and trade space for speed where it matters.
Here is a simple way to configure mod_rewrite to serve the compressed pages even if you do not have mod_deflate available.
First, compress all your HTML pages, e.g. using
find -name "*.html" | while read file; do gzip -9c < $file > $file.gz; done
Since I am using make to handle my web site, here is an extract that helps me keeping all compressed files updated when I upload the pages (also in parallel, when I pass e.g. "-j 5"):
TEXT_FILES=$(shell find -name "*.html" -o -name "*.css" -o -name "*.js") .PHONY: copy copy: $(addsuffix .gz, $(TEXT_FILES)) copy_website.sh %.gz: % gzip -9c $< > $@
Now we can configure mod_rewrite to prefer these compressed files for clients that support it. To do this, I put the following into my .htaccess file:
RewriteCond %{REQUEST_FILENAME}.gz -f RewriteCond %{HTTP:Accept-Encoding} .*gzip.* RewriteRule ^(.*[.])(html|js|css)$ $1$2.gz [L]
To spell this out:
- check if there really is a compressed version of the requested file available ("-f" tests for the path being a file).
- check if the client tells us that it accepts "gzip" compressed content
- if both conditions hold, redirect the client to the compressed file version.
Given that the compressed files are often 5x smaller than the plain HTML version, this saves lots of bandwidth from my web site with really little effort.