rails / sass-rails

Ruby on Rails stylesheet engine for Sass
MIT License
858 stars 333 forks source link

Sass generation time in rails is much longer than on command line #67

Closed tmeasday closed 9 years ago

tmeasday commented 12 years ago

My SASS is taking up to a few minutes on some machines to generate CSS files.

I've set up a new rails project with just the css files for reproduction: https://github.com/tmeasday/sass_rails_slowness

On my machine, running: time sass --compass app/assets/stylesheets/screen.css.scss > /dev/null Takes ~6s

Changing a scss file and running: time curl http://sass-rails-slowness.dev/assets/screen.css > /dev/null Takes ~20s

I'm running ruby-1.9.2p290 through rbenv.

On my colleague's machine the times are 23s and 40s.

Any ideas?

tmeasday commented 12 years ago

Further investigation:

I wrote a little test script that runs the Sass::Engine in more or less the same way that sass-rails does, but hardwired to a single file.

So it does this:

puts Benchmark.measure { out << engine.render }

Running it directly (with a rails environment) via rails runner gives benchmarks of:

9.300000   0.100000   9.400000 (  9.404537)

(I'm guessing the extra few seconds can be attributed to rails doing things like whiny_nils and other stuff I'm not aware of).

I then hardwired sass-rails to call this rather than actually doing work; so I changed template_handlers.rb line 94 from

def evaluate(scope, locals, &block)
  Sass::Engine.new(data, sass_options(scope)).render
end

To:

 def evaluate(scope, locals, &block)
    require '/Users/tom/Development/Percolate/sass_rails_slowness/script/tester'
    SassTester.render
 end

So that the exact same code path is run. When I run it via rake assets:precompile:primary, it reports:

16.640000   0.130000  16.770000 ( 16.752122)

So it's taking around 2x as long, with the same rails environment, running the exact same code. I can't for the life of me figure out what's going on here??

olivierlacan commented 12 years ago

This is a continuation of the behavior I presented in #36, except without errors displaying in the console anymore.

Still no news on this? It's been more than 4 months now.

Papipo commented 12 years ago

I think I am hitting this same issue in my app right now. Extremely high compilation times each time I touch any of my stylesheets.

tmeasday commented 12 years ago

@Papipo, if you haven't seen it, have a look at this gist.

I outlined some steps in there that we took to work around this problem. We've managed to get compilation times down to something more acceptable, so at least we can develop! A lot of the things we did are common sense in terms of getting the output CSS file down in size, which I think is desired anyway.

scottdavis commented 12 years ago

This isn't so much a problem with sass as it is a problem with the resolver in sprockets being slow im really starting to dislike Hike

tmeasday commented 12 years ago

Well, I am not sure about that. Because in my investigations above, I was using the same SassEngine with the same load paths and it was still taking twice as long. More information about the above, SassTester.render does more or less this:

module SassTester
  def self.render
    engine= Sass::Engine.new(HARDWIRED_FILE,
      :load_paths=>PATHS_TO_RAILS_STYLES_AND_COMPASS,...)

    puts Benchmark.measure { out << engine.render }
  end
end

As you can see, whether calling it from the bowels of rails or directly through a script, the load paths should be the same.

Of course I'm not 100% on top of how all this works, so there could be more to it that I don't get.

scottdavis commented 12 years ago

Right, but in sass-rails sass asks sprockets to find the file first and only until that search is exhausted does it search its own load path. Sprockets uses a gem called Hike to find dependent files. And we have noticed especially on the compass end of things that having a very large import stack makes HIke choke and it slows down a lot. For some more insight checkout this issue in this compass https://github.com/chriseppstein/compass/issues/516

This could also be a GC issue because when your running sass with rails your memory space is also going to be filled with rails if you want to verify this run some call graphs and you should see your process getting stuck in the Hike resolver or in the GC we have seen both appear in that thread above

tmeasday commented 12 years ago

Ahh, right. Thanks Scott, that makes sense then. Probably this bug can be closed then.

scottdavis commented 12 years ago

I would actually leave it open and probe the sprockets guys to why the resolver is so slow. It is becoming a real issue in projects with large @imports

Papipo commented 12 years ago

In my case is not about the size of the imports, in fact my app is faster if I import compass and blueprint entirely instead of their separate parts. The problem is having lots of dirs on the assets_path because of gems that add stuff there.

s1kx commented 12 years ago

I have the same issue with just only zurb/foundation 3.0.1 (that uses compass-rails) in my Rails 3.2.6 project.

Everytime I change anything in an @import'ed file (to use mixins):

Compiled application.css  (7092ms)  (pid 19786)
xdite commented 12 years ago

because foundation @import a lot of @base, and @base import whole @compass. so it will be ultra slow ...

knoopx commented 11 years ago

Here is my take on this:

sass (3.2.6)
sass-rails (3.2.6)
compass (0.12.2)
compass-rails (1.0.3)
sprockets (2.2.2)
hike (1.2.1)

A request just after modifying application.css.sass generates the following profiling report: http://d.pr/f/MWfo wich as you can see there's something really weird going on with Dir.open

Tried to debug that and then got this: https://gist.github.com/knoopx/5082439

It looks like everything is working properly (except some dup lookups) but I personally think that sprockets/sass integration is broken by design. @import directive should not delegate the lookup to sprockets or sprockets should be smart enough to figure an optimum lookup path.

Here are some design flaws that I suspect that are the culpable of our current performance issues:

voondo commented 10 years ago

Are there any news about this issue ?