@aldo, thanks for the info. I'll look into it. But it seems that I don't 
find any problems atm.

Meanwhile, I've been playing a bit around to see what happens during the 
precompilation task. (I used the task from rails head for testing, not 
the buggy one included in rails 3.1).

I have noticed the 2 loops:

      config.assets.precompile.each do |path|
        env.each_logical_path do |logical_path|
            ........
        end
      end

if first starts to loop over all files that need to be precompiled. My 
setting was a bit different. I had 4 extra files that needed to be 
precompiled. So that meant, 4 extra loops.

In the inner loop, it starts to loop over all the assets available.

First I thought this was the error. But it seemed like it only matches 
files that are ok by the result of the first loop. Not that big of a 
deal, the penalty for looping multiple times over the same asset list is 
pretty small.

I started to calculte the time it took to run the task localy:

real  0m31.001s
user  0m28.357s
sys  0m2.330s

So I started to tinker a bit with the config.assets.precompile. I don't 
use the application.css/js so they can be removed. So came up with this:

config.assets.precompile -= [/application.(css|js)$/]
config.assets.precompile += [/^(juggler|frontend).(css|js)$/]

Using this config setting, I was able to almost remove a whole second of 
the precompilation time :p

real  0m30.606s
user  0m28.409s
sys  0m2.324s

What I did noticed, was that precompiling my biggest js manifes took a 
lot af time. So I created a custom js compressor based on the jsmin gem 
and used that for precompilation:

config.assets.js_compressor  = JsminTransformer.new

The result was tremendous:

real  0m22.895s
user  0m20.884s
sys  0m2.008s

It takes almost 8 seconds less to precompile using jsmin instead of 
uglifier!

Since I was impressed, I retook a look at the 2 loops we encountered 
earlier. It seems like env.each_logical_path always calls up the same 
assets. But why do all the checks over again (see the sprockets base 
class)? Either way you put it, it's a IO penalty, when you check for 
files.

So I changed the rake task a bit. I call each_logical_path once and 
store the result (an Enumerable object) in a variable that I'll loop:

asset_list = env.each_logical_path

config.assets.precompile.each do |path|
    asset_list.each do |logical_path|
        ....
     end
end

So I ran the altered precompile task again and got this result:

real  0m18.404s
user  0m17.211s
sys  0m1.158s

Again, almost 4 seconds off the clock!

As a final test, I wanted to see if limiting the asset list while the 
script ran had some performance gain. So I tried to remove the assets 
that where already precompiled:

asset_list = env.each_logical_path.to_a
remove_list = []
config.assets.precompile.each do |path|
    asset_list -= remove_list
    remove_list = []

    asset_list.each do |logical_path|
        ....

        if asset = env.find_asset(logical_path)
      ...

            remove_list << logical_path
        end
     end
end

The end result was a bit slim, but still:

real  0m17.772s
user  0m16.548s
sys  0m1.189s


Now that I altered the deploy recipe to use my altered precompile task, 
everything seems to be in order, except the high cpu usage during the 
rake task. But this is due to I/O I guess while copying the files 
around.
At this point, I think I'll use my custom recipe, and precompile the 
localy like Jim suggested, so that I can avoid the the high load on the 
production machine.

At this point, I'm still curious of other findings that improve the 
precompilation of assets. So any info is welcome.

-- 
Posted via http://www.ruby-forum.com/.

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-talk?hl=en.

Reply via email to