Pre-Compressing Web Content

This was definitely a “D’oh!” type of problem.

One thing I’d been meaning to figure out for a while was how to send gzip-compressed files to a browser. That is, if I have a large HTML file, it’d be nice if the server could compress it to save bandwith and transmission time. Yes, Apache has mod_deflate which takes foo.html and gzips it on the fly, setting all the appropriate HTTP headers. But for static content, I should just be able to compress the file in advance. If the browser asked for foo.html, I wanted Apache to see that there’s a foo.html.gz and send that instead, with headers saying that it’s a text/html file that happens to be compressed.

mod_mime seemed like just the thing: just add

AddEncoding x-gzip .gz

to .htaccess. But every time I did that, Apache sent back “Content-Type: application/x-gzip“, so my browser treated it as a random file of unknown type that happened to be compressed.

Then I noticed that my vanilla-ish site-wide Apache config had

AddType application/x-gzip .gz .tgz

so that when Apache saw foo.html.gz, it ignored the .html extension, and saw only the .gz one.

The fix was to add RemoveType to my .htaccess:

RemoveType .gz
AddEncoding x-gzip .gz

And voilà! .gz stops being a file type and becomes an encoding, allowing .html to shine through.

I’ll add that this plays nice with AddLanguage as well. In my test setup, I have foo.html.en.gz, for which Apache returns the headers

Content-Type: text/html
Content-Encoding: x-gzip
Content-Language: en

I.e., it’s an HTML file, it’s gzip-encoded, and it’s in English.

Just as importantly, this works with other file types (e.g., CSS files and JavaScript scripts), and XMLHttpRequest does the Right Thing with them on all of the browsers I care about.

This entry was posted in Hacking, Things I've Learned and tagged , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s