Most default installations of Apache take care of this automatically via
mod_deflate (Nginx uses the equivalent
HttpGzipModule). Files are compressed on-the-fly and a
Content-Encoding: gzip HTTP header is added to the response. However, since Amazon S3 is just a place to store files it lacks the ability to gzip files in real-time before delivering them. When using a website speed test application like WebPageTest, this can result in informational warnings that look like this:
Use gzip compression for transferring compressable responses: 90/100 FAILED - (52.1 KB, compressed = 40.6 KB - savings of 11.5 KB) - http://mybucket.s3.amazonaws.com/css/awesomeness.css
To resolve this, files have to be compressed before being uploaded to S3. From Linux or OSX, this can be easily done with
gzip -9 awesomeness.css, which creates a new, compressed version of “awesomeness.css.”
This new file is then uploaded to S3 and the following metadata is set on the bucket object:
Content-Type header informs the web browser that the actual contents of the file is CSS markup while
Content-Encoding specifies that it’s a gzipped file. Both HTTP headers (“metadata” in AWS-speak) are required for the browser to correctly interprete the file.
Manually gzipping each file and setting the correct metadata can get very tedious, very quickly. I would recommend that this process be automated as a build step on a continuous integration (CI) server (at RBN we use Jenkins): a post-commit hook on the source repository fires, triggering a build. The CI server performs a SVN export or Git clone, executes a shell script that gzips the files, and uploads them to S3 and sets the proper object metadata. If you’re not currently using CI in your development workflow, a more basic version of this process can be hacked together using only commit hooks. Though I would argue that this would be an opportune time to dip your toes into continuous integration.