Hi, I'm Samuel Cochran

on Twitter, Facebook, Google, LinkedIn, GitHub, Stack Overflow, and Xbox Live.

The Asset Pipeline Isn't Actually Slow

Do you hate how long it takes to run rake assets:precompile? If you just want the fix, here's a patch.

Precompiling should actually be blisteringly fast. At least on subsequent runs, even with modified assets. Well, as fast as you can be while requiring a rails environment to boot. I've dug around inside sprockets enough to know that turbo-sprockets-rails3 should be completely unnecessary for a correct configuration, which made me question what rails was doing.

There's a simple mistake introduced by an innocuous-looking commit. It moved the prerequisite tmp:cache:clear from assets:clean, run by you when you want to blow away your assets, to both assets:precompile:digest and assets:precompile:nondigest, sub-tasks of assets:precompile.

Not only does this mean that right before the asset pipeline needs its cache is it blown away, twice, but all of your application's cache is gone too. Do you deploy frequently, running the precompile, and still use the default file-based rails cache? You're probably not getting much benefit from caching.

Sprockets, the library powering the asset pipeline, is actually really well designed. One of the primary requirements is the ability to cache assets as much as possible. In development, this works great. Only the files you are currently editing cause sprockets any sweat, the rest are just served straight out of the cache. The same benefits are perfectly applicable to the precompilation process. Unless the cache is emptied just before you precompile. Twice.

In any case, there's a pull request for rails 3.2, a temporary fix for now, and it's already better in sprockets-rails for rails 4.

Update:

My pull request has been rejected, and was apparently a duplicate.

The only caveats, as mentioned on the pull request, is this doesn't cope with asset environment changes, and may reference digest assets from the nondigest versions. You can run assets:clean for the former and I only use digest assets for the latter, so these don't bother me.

The fundamental problem is that there should never have been a digest and nondigest version of assets built by default. There should be one sprockets environment per rails environment. This is how sprockets-rails appears to work, and is how I suggest you configure your assets too.

A sprockets environment config fingerprint prefix would be even better, so switching compressors/digests/etc would also implicitly invalidate the cache. Perhaps I'll have a look at that.