Friday, 5 September 2014


The Problem:

Even with the asset pipeline, content is transmitted to the end user over their, sometimes slow, connection. Distance plays a role in the speed at which data can be delivered. Because of this, users further away from your servers get a sluggish experience. This decreases both the users’ patience and your ability to effectively engage them.

The Solution:

CDNs are networks of servers that host your content so that when you make a request, the request is served from a server closest to you. This can often reduce transmission time by several seconds (…think users in Asia requesting content that’s served from Virginia – this is the case if you deploy to Heroku).

The use of a CDN also reduces the number of requests to your application servers. Most Ruby applications use Nginx or Apache in front of the Ruby processes. These HTTP servers are really good at serving static content, but no one will deny – the fewer requests, the better.

Option 1: Push your assets to the CDN during deployment

Depending on your method of deployment, pushing assets to a CDN isn’t always trivial. The asset_sync gem has made this relatively straight forward if you choose to host your assets from Amazon S3. Out of the 2 options, this is the most efficient because all requests for assets will be diverted away from your application, leaving its precious processing power to serve more important application requests.

Option 2: Assets are pulled to the CDN on first request

This option won’t change deployment and is simple to setup. The only downside is that upon first request to an asset, the CDN will pull it from your web server and cache it (it’s hardly a downside if you’re currently serving all your assets from your web server). All subsequent requests to that asset will be served straight from the CDN. The simplicity of this option generally makes it my preferred option.

So let’s get to it…

Amazon Cloudfront:

Log in to your Amazon EC2 account and click “Cloudfront”:

"Click Cloudfront in the AWS web console"

Click “Create Distribution”:

"Create a Cloudfront distribution endpoint"

Enter the domain where your assets currently live (ignore Origin ID – it’ll be filled in for you):

"Settings for a typical CDN"

Make note of the Cloudfront distribution URL

"Cloudfront distribution URL"

In Rails application:

Rails provides and easy way to change the host URL of the assets (images, stylesheets, javascripts, fonts…). Enter the Cloudfront distribution URL from above as the Rails asset_host.

# config/environments/production.rb
config.action_controller.asset_host = ""
At this point, the domain of all Rails asset helpers image_tag, stylesheet_link_tag, and javascript_include_tag will be prefaced with the asset host URL that you configured above.

For example:

Note: if you only change config/environments/production.rb, you won’t see any changes in your development environment.

And that’s it!

1 comment: