by James Coglan

Menu

UPDATE: Safari doesn’t seem to play well with this – I’ve modified the code
so that Safari is served regular uncompressed files. Also, I realised that the
code went about things in a slightly roundabout way, so I’ve shuffled it around
a little.

What with the fact that optimising Sylvester for speed is causing its
brief, legible internals to balloon into reams of hard-coded arrays and unrolled
loops, and the fact the fact that Prototype‘s latest release has put on a
few extra chins (1.5.1 is 97kb compared to 1.5.0’s 70kb), I thought it was about
time I figured out how to serve my JavaScript like a grown-up. Most of what’s
written online seems to be focused on specific platforms (PHP, mostly) and I
thought something a little more generally useful was needed.

The general approach to gzipping your web content seems to run as follows:

Check the user agent will accept gzip-encoded content.

Have your application code filter its output via a gzip function, or have
Apache do this for you.

Fiddle around with .htaccess to add the correct content type.

The problem with doing all that is that, well, you have to do all that.
Compressing assets on the fly is probably not the most efficient way of doing
things, and I’m not a huge fan of having your application deal with content
delivery – the server should be doing that.

There is a way to have all this handled in a few lines of .htaccess, providing
you put in a couple of minutes effort compressing your files by hand. Let’s say
you have prototype.js sitting on your server. Gzip it (use 7-zip or
similar if you’re running Windows) to give you a file called prototype.js.gz.
Stick this in the same directory on your server. If you’re comfotable with the
command line, you can just SSH into your box and do, for example:

gzip foo.js -c > foo.js.gz

Then, add the following to .htaccess in your document root (preceed this with
RewriteEngine On if you don’t have it somewhere already):

The first line tells the server that files with .gz extensions should be served
with the gzip encoding-type, so the browser knows what to do with them. The
second line checks that the browser will accept gzipped content – the follwing
lines will not be executed if this test fails. We exclude Safari as it doesn’t
interpret the gzipped content correctly. We check that this gzipped version of
the file exists (fourth line), and if it does, we append .gz to the requested
filename.

With this in place, all you have to do is upload gzipped copies of your files to
your server and Apache will serve whichever version of the file is most
appropriate – you don’t have to change your <script> tags or any application
code.

One final platform-specific extra for those of you on Rails: I cannot recommend
AssetPackager highly enough. The base package for an app I’m currently
working on includes Prototype and various commonly used widgets of mine, some of
which are packed. The package totals 125kb as separate files, 99kb using
AssetPackager, and a measly 26kb when you throw gzip into the pot.

—

If you’ve enjoyed this article, you might enjoy my recently published book
JavaScript Testing Recipes. It’s
full of simple techniques for writing modular, maintainable JavaScript apps
in the browser and on the server.