Quickly Enable Really Fast CDN Assets with Google PageSpeed and Amazon CloudFront

(without affecting your development process)

Alex Ford
5 min readFeb 28, 2014

Serving static assets directly from the web server is a thing of the past.

I’m going to show you how to automatically combine, compress, cache, and deliver CSS, JS, and image assets as fast as possible. The best part: you don’t have to change your development process, and it works with static sites, CMSes, and full-blown web apps.

To do this, we’ll be using Amazon CloudFront’s CDN service with Google’s PageSpeed module.

The prerequisites for this method are an Apache/Linux based web server (you’ll need root shell access), an Amazon AWS account, and access to modify your domain’s DNS records. I’m assuming you’re comfortable with configuring Apache VirtualHosts and general Linux shell tinkering.

The basics can also be applied to other environments pretty easily, but I’ll leave that as your homework. Specifically, nginx can be used but requires compiling from source.

Step One: Set up CloudFront and DNS

This step takes some time to take effect (anywhere from a few minutes to a few hours), so we’ll knock it out first.

Log in to your AWS account console (sign up for AWS real quick if you don’t have an account—it’s free to get started and you are only charged for usage) and set up a new CloudFront distribution. AWS will first ask if you want a “Web” or “RTMP” distribution. You want “Web”.

Point the distribution’s origin to your production website domain, and add “assets1.yourdomain.com”, “assets2.yourdomain.com”, and “assets3.yourdomain.com” as “Alternate Domain Names (CNAME)”.

The settings will look something like this:

I have stripped out some settings from this screenshot for brevity

This is telling Amazon that your CloudFront distribution should 1) use your website as the “origin” (original source) of the files it serves and 2) to respond to requests for those assets subdomains. The “Default cache” settings can be left alone for our purposes. If you need to use SSL or want to enable logging, you can do so as well.

Once the CloudFront distribution is set up, log in to your DNS manager (provided by your domain registrar or hosting company, depending on your setup). Add CNAME records in your domain for “assets1", “assets2", and “assets3" that point to the long ugly domain name provided by AWS for your new distribution (something like xxxxxxxxxxxxx.cloudfront.net). Save the new DNS records and move on to step two while your DNS and AWS settings propagate.

Step Two: Install PageSpeed

Next we’ll install Google’s PageSpeed on to your web server. PageSpeed is an open source module that automatically scans the HTML in responses from Apache for static assets, then rewrites the response to include references to optimized/combined versions of those assets that it has created on the fly.

The optimized assets are given optimal cache headers (such as a far future “Expires:” header) as well as cache-busting filenames. It will also optimize your files, and minify your JavaScript. (“Also makes julienne fries!”) Check out PageSpeed’s website for more background.

PageSpeed is sweet.

If you’re running Ubuntu/Debian, installing is as simple as these shell commands (if you’re not, see the PageSpeed install instructions for more info. In fact, read those anyway):

sudo dpkg -i mod-pagespeed-*.deb
sudo apt-get -f install

Restart Apache!

Step Three: Configure PageSpeed to rewrite asset URLs to CloudFront

Open up the Apache configuration file for the VirtualHost running your website. This is probably in your Apache “sites-available” path. On Ubuntu this is probably in /etc/apache2/sites-available

In the root VirtualHost configuration, just inside the <VirtualHost *:80> portion, add the following:

ModPagespeedShardDomain http://yourdomain.com http://assets1.yourdomain.com,http://assets2.yourdomain.com,http://assets3.yourdomain.com

Then, inside the <Directory> block that points to your root directory:

ModPagespeed On
ModPagespeedAllow all
AddOutputFilterByType MOD_PAGESPEED_OUTPUT_FILTER text/html
ModPagespeedEnableFilters combine_javascript,extend_cache,resize_rendered_image_dimensions

Some of those ModPagespeed filters are optional, but I like them. There are all kinds of filters you can enable if you feel like tinkering. Find what suits your needs.

So, your VirtualHost declaration will look something like this, all-told. I’ve removed some extra things here, of course, to show only the relevant pieces:

<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName yourdomain.com
ServerAlias www.yourdomain.com
ModPagespeedShardDomain http://yourdomain.com http://assets1.yourdomain.com,http://assets2.yourdomain.com,http://assets3.yourdomain.com DocumentRoot /var/www/yoursiteroot/ <Directory /var/www/yoursiteroot>
ModPagespeed On
ModPagespeedAllow all
AddOutputFilterByType MOD_PAGESPEED_OUTPUT_FILTER text/html
ModPagespeedEnableFilters combine_javascript,extend_cache,resize_rendered_image_dimensions

</Directory>
### Other VirtualHost-y stuff </VirtualHost>

Restart Apache again, and reload your site. Reload your site again. Look at your site. Now back at me. Now back at your site—now back at me. Open up the web inspector of your choice and check out the network requests. You’ll see requests for your assets pointing to your assets subdomains, which are being routed to Amazon CloudFront, which will in turn start storing your assets and delivering them very quickly.

It works! How?

You, now. Hopefully.

Setting up PageSpeed to generate optimized, minified, and versioned copies of your assets is already a speed improvement.

Through the magic of “sharding”, we can turbocharge the delivery of those files. This declaration:

ModPagespeedShardDomain http://yourdomain.com http://assets1.yourdomain.com,http://assets2.yourdomain.com,http://assets3.yourdomain.com

Tells PageSpeed to rewrite the URLs to the assets it has optimized across the “assets” subdomains, rather then the original domain. This means that the browser will look for /css/main.css (for example) at http://assets1.yourdomain.coym instead of http://yourdomain.com. This re-routes requests to your assets to CloudFront rather than your server!

Additionally, because we are supplying three separate assets domains, PageSpeed will distribute requests for assets to these three domains. This is important because browsers limit the number of requests they’ll make to one domain at a time. By “sharding” the domains out like this, browsers will make more parallel requests to your assets rather than waiting for one to finish downloading before grabbing the next. Google’s explanation of sharding with PageSpeed helps explain that a bit better than I can.

Here’s where CloudFront comes in:

The first time CloudFront receives a request for an asset (like http://assets1.yourdomain.com/css/main.css), it will hit the “origin” you specified in the settings (yourdomain.com) to grab the file and return it. Subsequent requests will not require a trip to your origin server—CloudFront will send its own copy post haste.

Generally, pushing updates to CloudFront assets could be a pain. Changing your CSS file might take a while to propagate to CloudFront, for instance. However, because PageSpeed is already creating copies of your assets with versioned filenames, updates to your files look like new files to CloudFront, so it hits your server for them immediately, solving that problem. CloudFront also passes a long the far future “Expires:” header that PageSpeed ads, so browsers will hold on to your files in their own cache for a long time.

This all adds up to really, really fast assets.

I hope this overview/tutorial helped you make your website faster.

If you have any issues or suggestions, please don’t hesitate to drop me a line via Twitter! It’s very possible I’ve missed a step or left out a detail that will help you along. I’m here to help.

If you’d like to just hire someone to set this up on your system, I can help!

--

--