Incremental Web Performance Improvements

Compression (gzip) of front end resources (js/css)

When we moved to Amazon’s Cloudfront (CDN), we lost the ability to serve gzipped version of our script files and stylesheets. We are single page app and we have a large javascript and css footprint and this was greatly affecting our application performance.  We had two options to fix this.

  • Upload a gzip version of the resource along with the original resource and set the content-encoding header for the file to gzip. CDN would then serve the appropriate resource based on request headers.
  • Use a custom origin server that is capable of compressing resources based on request headers. The default origin server which is a simple Amazon Simple Storage Service (S3) is not capable of this and hence the problem.

Fortunately for us, all our application servers use apache as a web server and we decided to leverage this setup as our custom origin server. We had to simply change our deployment process to have front-end resources deploy to our app servers as against a S3 bucket. This does make the deployment process tiny bit complex, but the benefits are huge.

 

Dividing our main javascript module into smaller modules.

As mentioned earlier, we are single page app and have a large javascript footprint. We bundle all our javascript files into a single module and fetch it during our app initialization. And as we grow, so will our javascript footprint and did not want to run into long load times during our app initialization as demonstrated by Steve Souders in his book: High Performance Web Sites.

We use requirejs to build all our javascript modules into one single module. Fortunately enough requirejs provides for combining modules into more than one module in a very flexible manner. We package all our “common” modules and the main module we would need on loading the application into one module. All other modules are dynamically loaded based on when they are required. More specific details will be posted soon.

Pre-caching our main javascript module.

I believe this is a very common practice and simple implementation that does reap a huge performance benefit. We now pre-fetch our main javascript module during our login process using iframe and html object tag. The iframe keeps the login page load times independent of the resources being fetched through it. Again, there are many ways to implement this as mentioned by Steve Souders, but we chose this for simplicity.

Additional Links

  • http://stackoverflow.com/questions/5442011/serving-gzipped-css-and-javascript-from-amazon-cloudfront-via-s3
  • http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html
  • http://requirejs.org/docs/optimization.html