How to serve compressed HTML, JavaScript and CSS

This article deals with the reduction of size of static web pages, web pages which do not change each time they are served.

Why gzip static pages?

Compressing static web pages (web pages which do not change each time they are loaded) with gzip (see The gzip home page) reduces the total amount of bandwidth used serving web pages, and reduces the time it takes a page to travel across the internet, because the file is smaller.

This is effective for HTML, JavaScript, CSS or text files, but image formats such as JPEG or PNG files are already compressed, so there is no point in gzipping them, since the file size will not reduce by very much.

How to compress your files

You need to have the gzip utility to compress files. This is standard on Unix, Linux, and BSD computers. It is also available for Windows. See Gzip for Windows.

Using the command line, apply gzip --keep file.html to each file. This creates a file called file.html.gz. (The --keep option stops gzip from deleting the original file.) If you have a lot of files, the following Perl script automates the gzipping process:

#!/usr/local/bin/perl
use warnings;
use strict;
# Set $verbose to a true value if you need to debug this script.
my $verbose;
use File::Find;
find (\&wanted, ("."));
sub wanted
{
    if (/(.*\.(?:html|css|js)$)/) {
        my $gz = "$_.gz";
        if (-f $gz) {
            if (age ($_) <= age ($gz)) {
                if ($verbose) {
                    print "Don't need to compress $_\n";
                }
                return;
            }
        }
        if ($verbose) {
            print "Compressing $_\n";
        }
        # The following substitution is for the case that the file
        # name contains double quotation marks ".
        $_ =~ s/"/\\"/g;
        # Now compress the file.
        system ("gzip --keep --best --force \"$_\"");
    }
    else {
        if ($verbose) {
            print "Rejecting $_\n";
        }
    }
}

# This returns the age of the file.

sub age
{
    my ($file) = @_;
    my @stat = stat $file;
    return $stat[9];
}
Run this from the top public directory, and it will find and compress any file ending in .html, .css, or .js (case insensitive).

How to make Apache serve gzipped files

If you are using the Apache webserver, make your site serve a gzipped version of a file, if it is available, by adding the following to a file called .htaccess (see Apache Tutorial: .htaccess files) in the top directory of your public directory:

RewriteEngine on 
RewriteCond %{HTTP:Accept-Encoding} gzip 
RewriteCond %{REQUEST_FILENAME}.gz -f 
RewriteRule ^(.*)$ $1.gz [L] 
This tells Apache to serve the file ending in .gz if it is available as if it was the original file, if the requester accepts the gzip encoding. So this assumes you have files like index.html and index.html.gz or program.js as well as program.js.gz.

How to test whether it's working

The website HTTP Compression Test (whatsmyip.org) lets you test whether the gzipping is working OK or not. Type the URL of the static page which should be compressed into the box, and it will give you a green tick if compressed content is being sent OK. Google webmaster tools also has a facility to do this, but it's not quite as instant.


This article was originally written for the internal Wiki of web hosts NearlyFreeSpeech.net. I'm also publishing it here publicly for the benefit of non-members. If you are a member of NearlyFreeSpeech.net web hosts, you can view this page at https://members.nearlyfreespeech.net/wiki/HowTo/GzipStatic.



Copyright © Ben Bullock 2009-2012. All rights reserved. For comments, questions, and corrections, please email Ben Bullock (ben.bullock@lemoda.net) / Privacy / Disclaimer