How to debug a Rails asset precompile which is unbearably slow

This may not entirely answer your question, but I believe it is a decent enough start. As you’ll see, the precise answer will depend on the individual application, gem versions and so on.

So. For asset-related work, as you know, Rails uses a library called Sprockets, which in newer versions of Rails is, I believe, hooked into Rails as a Railtie. It initializes a Sprockets “environment” that can do things like look at your asset manifest, load those files, compress them, give the compiled assets sensible names, etc.

By default, that Sprockets::Environment logs its activity to STDERR with a log level of FATAL, which isn’t very useful in these situations. Fortunately, the Sprockets::Environment (as of 2.2.2) has a writeable logger attribute that you can patch in via Rails, using an initializer.


So, here’s what I suggest, to start:

In config/initializers, create a file, something like asset_logging.rb. In it, put:

Rails.application.config.assets.logger = Logger.new($stdout)

This overwrites the default logger with one that will spit more information out to STDOUT. Once you’ve got this set up, then run your asset pre-compilation task:

rake RAILS_ENV=production assets:precompile

And you should see slightly more interesting output, such as:

...
Compiled jquery.ui.core.js  (0ms)  (pid 66524)
Compiled jquery.ui.widget.js  (0ms)  (pid 66524)
Compiled jquery.ui.accordion.js  (10ms)  (pid 66524)
...

But, in the end, the final answer will depend on:

  • how “deep” you want to go with logging this asset stuff
  • what specific version of Rails, Sprockets, etc. you’re using
  • and what you find along the way

As you’ve already learned, log spelunking at the Rake task level, or even at the Rails level, doesn’t give much information. And even making Sprockets itself verbose (see above) doesn’t tell you too terribly much.

If you wanted to go deeper than Sprockets, you can probably monkey patch the various engines and processors that Sprockets dutifully chains together to make the asset pipeline work. For example, you could look into the logging capabilities of these components:

  • Sass::Engine (converts SASS to CSS)
  • Uglifier (JavaScript compressor wrapper)
  • ExecJS (runs JavaScript in Ruby; a dependency of both Sprockets and Uglifier)
  • therubyracer (V8 embedded in Ruby; used by ExecJS)
  • etc.

But I will leave all that as “an exercise for the reader.” If there’s a silver bullet, I’d certainly like to know about it!

Leave a Comment