One of the first steps in improving front-end performance is to migrate static assets to a content delivery network, such as Amazon’s CloudFront or Akamai. CloudFront is particularly attractive with its pay-as-you-go model, tiny upfront investment and ease of use.
Your existing web server may already be set up to compress JavaScript and CSS, potentially saving hundreds of kb on the wire. In uploading and testing your assets on CloudFront you’ll soon realise that it doesn’t perform any gzipping or compression. How to benefit from Amazon’s superfast edge locations and smaller file sizes?
When your browser requests a page, the headers sent might look like the following:
Host: www.davidcaunt.co.uk
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729) FirePHP/0.3
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.8,en-gb;q=0.5,en-us;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://www.davidcaunt.co.uk/about/
The header we’re interested in here is Accept-Encoding – this denotes whether the browser can cope with gzipped assets, and is used by Apache to decide whether to compress them. We can use this header in our PHP scripts to reference pre-compressed assets, and here’s how:
- Compress asset, e.g. home.css -> home.cssgz
- Upload both files, home.css and home.cssgz to S3 (CloudFront)
- Add PHP code to link to the compressed file if the browser accepts
You can easily compress assets on Linux using the following:
gzip home.css
In step 2, you’ll need to inform S3 that your assets are gzipped. S3 allows you to specify headers that will be sent with your file:
Content-Encoding: gzip
All good libraries and gui tools will help with this. It also makes sense to set Expires headers, if your assets are versioned.
Then the following PHP snippet should be all you need:
if (false !== strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')){
$path = '/css/home.cssgz';
}else{
$path = '/css/home.css';
}
You’ll want to integrate this code into your View Helpers (Zend Framework) or application code for generating asset URLs.
Note
You’ll notice I’ve named my file home.cssgz, not home.css.gz. I had problems with Safari PC (and probably Mac) refusing to use these files inline, and being disposed as attachments.