Making Rails asset pipeline faster

We all know that for a rather large Rails app where the front-end is quite stuffed, the asset pre-compilation and more importantly - development mode changes are far from instantaneous.

The front-end we're referring to is the kind that makes heavy use of sass, sass libraries (Compass, Bourbon, etc.) and transpiled JavaScript languages (like the old CoffeeScript, ES6, etc.)

Replacing Ruby Sass with libsass

On the Sass front for quite some time there's a pure C/C++ implementation of the Sass CSS precompiler: libsass . Clearly, being implemented in C/C++ this means it should run orders of magnitude faster than the Ruby implementation.

All we need is a gem that uses it: enter sassc-rails which is a drop-in replacement for the sass-rails gem.

How fast is sassc-rails compared to the vanilla gem in the real world? (benchmarks straight from their repo)

Not really orders of magnitude faster but then again a 4.5x is not bad at all.

The only issue with this is that it doesn't fully work with the usual sass gems like Compass and more i.e. before using it in production make sure it can actually compile your scss files without issues.

To help with that you can check the Sass Compatibility website and run your app with the gem installed in a different branch to test things out.

Compass intermission

What grinds my gears is that Compass doesn't work at all with sassc-rails:

Replacing the JS transpiling/minification/etc. with mini_racer

The problem with therubyracer is that it uses version ~> 3.16.14.0 of libv8 ("a gem for distributing the v8 runtime libraries and headers in both source and binary form") whereas mini_racer uses ~> 5.1 which as one might expect is quite faster than the former.

Here we are talking about a 10x improvement i.e. really nice gains and thus an order of magnitude faster. On the compatibility side this seems to be a drop-in replacement i.e. so far in the apps I've added it in the Gemfile there were no issues whatsoever.

Alternative to mini-racer for best possible performance

Sprockets uses ExecJS which “picks the best runtime available to evaluate your JavaScript” this means that if you don't mind having an extra dependency installed you can just use Node.js 6.x to get the maximum performance.

Since I deploy my assets by precompilling them locally I just installed Node.js 6.2.0 via brew brew install node and ran time rake assets:clobber assets:precompile on a 2K lines CoffeeScript JS file. Without further ado, here are the results:

Should I use these in production?

In a set-up where the assets are pre-compiled locally then uploaded to the actual VM this is not a big issue i.e. if something fails just revert to the original gems.

Mini-racer looks rock solid so far whereas sassc-rails still has issues with some libraries i.e. not ready for production in all use-cases yet.

If you don't mind installing node.js and want maximum performance then by all means do it since it works flawlessly with ExecJs.

In the optimal case where you can integrate both into your Gemfile you will get quite a nice boost during deploys and more importantly: during development (in apps with large sets of assets of course).