Compress And Client Side Caching Static Content With AWS S3 And CloudFront

I was given an assignment to improve our page load speed after we moved from Akamai to AWS CloudFront. The page load time increased after the switch and this raise some concern, Google’s Page speed and YSlow showing lots of warning which was no shown previously when we are using Akamai.

Few of the factors that cause the slowness are Compression and Caching was not enabled in S3 and CloudFront.

If your storing all your static files in a IIS or Apache server, there are already easy ways to enable compression to your static files. What about S3 and CloudFront!? There isn’t any options for me to do it at the admin console.Took me quite sometime to find the solution as AWS forums and their information didn’t provide and clear answer to me.

Prerequisite

  • 7-Zip
    http://www.7-zip.org/
  • Amazon Web service (AWS) S3
  • AWS Cloud-Front
  • CloudBerry Explorer for Amazon S3 (Free Edition). Download here.
  • What you need to do at your Code

Size Comparison

Check out the size difference after “GZip-ing” your css/jsAWS S3 Gzip-ing comparisonNormal jq.js in firebug

Firebug checking

Gzip-ed jq.jsgz in firebug
Checking in firebug

Walk through

GZip-ing

1) Download 7-Zip and installed to your desktop
2) Start zipping your files
3)Choose “Archive format” as “gzip” format highlighted at the image below.
4) Rename your file extension from “.js.gz” to “.jsgz” and your ready to upload to S3.
Rename your file extension

 

AWS S3

1) Talk to the infra guys and ask them to create a AWS S3 account for you.
2) Download CloudBerry Explorer for Amazon S3 and setup it to access your S3.
3) Start uploading your files to S3 by drag and drop your files to CloudBerry Explorer.
**You are required to upload both the original file and the gzziped files

4) The following dialog box will pop up everytime you drag a file into the explorer. Click on “Set http headers” first
Cloudberry S3

5) Start adding the following http headers to your files.
Cache-Control: max-age=31536000, no-transform, public
Content-Encoding: gzip
Content-Type: application/x-javascript (or text/css depends on what file type you have ziped)
Expires: Tue, 01 Jan 2030 03:54:42 GMT (Pick a date that is far far away from todays date)

**31536000 = 1 year
** You DON’T need to set ‘Content-Encoding: gzip’ for non gziped files.
It will look like something as below once you finish adding the headers.

Set Http Headers

 

What you need to do at your Code 

This is the code to check if the client’s browser support gzip, if not support, will return the normal file. Below are a sample done with ASP.NET and C#:

public static string GetStaticFiles(string fileUrl)
{
    if (HttpContext.Current.Request.ServerVariables["HTTP_ACCEPT_ENCODING"].Contains("gzip"))
    {
      fileUrl = fileUrl.Replace(".css", ".cssgz").Replace(".js", ".jsgz");                
     }
 
     return fileUrl;
 }

 

<script src="<%=GetStaticFiles("http://www.domain.com/js/scripts.js")%>" type="text/javascript"></script>

 

Lesson learn

Lesson 1: iPad & Mac OS’s safari doesn’t accept .gz
Solution: change file extension from .js.gz to .jsgz

Lesson 2: IIS treat .js.gz or .jsgz as file
Solution: If your local/test environment is not referring to the AWS S3, put the “gzip” key at your configuration file. So that you can switch on or off serving gzip-ed contents without changing your codes.

References