While building Monocle, I noticed that deploys to Heroku were taking absolutely ages; specifically the asset pre-compilation stage. I tried a variety of things, including removing a bunch of CoffeeScript files, but deploys were still taking in the order of several minutes.
After talking to Josh, it seems the solution is a simple one. Simply enable Memcache caching for sprockets during the pre-compilation stage. By doing this, I’ve reduced asset compilation from 100 seconds to between 4-9 seconds.
By default, each Heroku deploy is in a isolated environment. This means that Sprockets can’t take advantage of previous asset compilations, and has to compile everything from scratch. The solution is to have a shared cache between deploys.
If you’re using Heroku, the first step is enabling a Memcache addon. I’ve gone with the
memcachier service, as they’ve got a generous free plan (which is all we need at this stage).
heroku addons:add memcachier:dev
Then we need to make sure the environmental variables are available to your app during the pre-compilation stage. Usually this isn’t the case on Heroku, but they’ve got a new labs feature called
user-env-compile which will do the trick.
heroku labs:enable user-env-compile
Next you’ll need to add the
memcachier gems to your Gemfile. Finally, the last step is to configure Sprockets.
I’m using Sinatra, so I’m configuring Sprockets manually. I’ve written a wrapper around the Memcache gem Dalli to ensure it exposes the sort of interface Sprockets expects.
assets = Sprockets::Environment.new assets.cache = Sprockets::Cache::MemcacheStore.new
With Rails, just configure the assets cache store in
config.assets.cache_store = :dalli_store
Welcome to faster deploys!