17

I'm having performance issues on a Rails 3.1.0 application, now I've done dome changes on my queries with AR and so but views still takes too many time to render, I've divided the views, loops and so, on many partials that are rendered dynamically inside views and inside other partials.

So it's a bad practice to have a large number of partials?

Should I reduce the number of partials to improve the views rendering time?

Thanks

6 Answers 6

5

I know about no significant rendering performance difference between many partials and one single view when you render the same content.

Obviously, if you render only some partials in some cases and others in other cases, such effectively reducing the rendering volume of a specific view, than you may gain some speed.

On the other hand, I always considered partials abstractizations which should be used at least from 2 different places to justify their existence. The other reason to use partials is when you want to render the same view but load different partials based on some business logic you have.

UPDATE:

I can't offer a measurement or some concrete numbers about the rendering speed. If you use a partial in a view, to render it you call the render method, so there is a second method call. This, as I said in my answer, is almost nothing but may help speed up things a very little.

However I never heard of a project fixing its performance problem by removing partials. Partials are a good way to offer a reuse mechanism to views and from the programmers view they should be used for that scope. They should be abstractizations for common concepts in views.

I worked on a project where partials were excessively used. Not Rails, but same MVC principles. Using little partials for everything you can imagine makes them hard to find when you start to have dozens of them. Where would you look for an input to be modified? In the view? In a partial? In which partial, there are 4 partials for this view? ...

After some hard refactorings, with each update of a view, we removed the unnecessary partials. They did not disappeared completely, but what remained are abstractizations which are well defined for the project. They represent well understood elements (like a tree for some kind of objects, or a specific list type) which repeat in a form or other on several views. I know if I see a tree that there is a partial for that. I know when I see certain type of list that there is a partial for that. I don't have hunt them down.

Code readability is the most important thing one can do for a software code base.

3
  • So basically, if i don't really need a partial, if that code will not be reused by other controller o reloaded dynamically i should't use partials? and this would improve the views rendering time?
    – Mr_Nizzle
    Jul 20, 2012 at 14:52
  • @Mr_Nizzle: I updated my answer to cover the problems rose by your comment. I hope this expended explanation is more understandable ... I just realized that my second paragraph in the answer can be misunderstood. Jul 20, 2012 at 20:41
  • Thanks man Code readability, that's what's all about.
    – Mr_Nizzle
    Jul 20, 2012 at 20:49
24

I disagree with both answers. I have copied and pasted the code from a partial into the position that it is present in the parent view partial and with 500 iterations, this takes a huge 600ms off the time take to render the view. <%= render xyz %> is in my opinion very broken.

Example, total time to render view:

Before:
5759.8ms
5804.2ms
5973.6ms

After:
5268.7ms
5201.6ms
5222.4ms

Diff = 5846 - 5231 = 615 ms

Edited

I ended up unDRYing all _partials within the _model partial and got it down to ~2000ms, at which point I tried moving the _model partial into the index however this did NOT have any affect on rendering times so I guess it's with calls to nested render that does it.

5
  • Interesting finding on nested partial. Did you mean unDRYing one partial reduced 600ms, and unDRYing all partials reduced 3800ms? Could you release the demo app for that?
    – lulalala
    Jun 19, 2013 at 9:32
  • @lulalala yes exactly, and sorry I can't as it was for my work and I've now moved it off Rails to Django so not even in touch with that code anymore. Looking at Wyatt Barnett has answered, I'm also now not sure if actually under the hood the partials were doing inefficient DB accesses which my unDRYed code was somehow avoiding.
    – AJP
    Jun 19, 2013 at 10:38
  • 1
    I've found the same thing. Taking code out of partials and unDRYing up the view gave me ~450ms performance increase as well.
    – bcackerman
    Mar 12, 2014 at 3:01
  • 1
    In my experience using Rails with HAML views, lots of small partials does slow rendering significantly. There seems to be a fixed overhead for every partial, as well as garbage collection kicking in when rendering a lot of partials in a view. Inlining a partial used in a table of 50 items reduced the page rendering by 500 ms.
    – d4n3
    Dec 11, 2014 at 8:16
  • 2
    Rails 4: I just removed a few thousand nested partials on a big app and got a huge speedup. Don't have the numbers, but yeah, if you are having performance problems it would be worth removing some nested partials to see if it helps.
    – Rick Smith
    Jul 9, 2015 at 20:49
5

Not a rails guy, but Partial Views are likely not the problem per se. Rather, it sounds like you are doing a bit of SELECT N+1. Look at things from the DB server's perspective to make sure you aren't beating it to a pulp.

3

Even if you have no n+1 problem and do all the database work up front (say with a recursive CTE), nested partials are still very slow. Haml and Erb both look slow to me. On Rails 5.1.4 I'm seeing a few milliseconds for each partial, plus occasional partials that are much worse (probably corresponding to garbage collection).

I noticed that if I rename the partial while one of these requests is running, I immediately get an error about how the file is not found. So apparently Rails is reading the partial off disk, reparsing it, and evaluating it for each iteration. No wonder it's slow!

2

Working on a Rails 4.2 app right now where a slow action that was taking about 745ms on average.

When I remove the code from the partials and place it into the main template, the time it takes is now averaging less than 25ms.

The number of calls to render the partials was only 29.

1
  • 2
    On this point found the following helpful from 42 performance tips for Ruby on Rails :: Do not render with a loop : If you have an each-loop in your views for example to render a partial for each item in a collection then this can get very expensive. Instead, use the collection rendering feature like so: <%= render partial: 'item', collection: @item, as: :item %>. This is a lot faster because in that case Rails will only initialize the template once rather than once for each item if rendered with a loop.
    – 3ygun
    Apr 14, 2020 at 19:50
0

A lot of the slowness being seen in nested partials happens only during development. Switch to production to test.

2
  • Perhaps you could comment on why the development version is appreciably slower, and be more nuanced about when to use which mode for what testing.
    – Kain0_0
    Jan 10, 2019 at 0:44
  • frankly i don't know all the details, i just know I was having the same issues, and found it was much improved when I switched to production. I can guess that as Paul Jungwirth noticed, the rereading of the partial and reparsing, happens during development when files may have changed.
    – Zapaf
    Feb 27, 2019 at 7:37

Not the answer you're looking for? Browse other questions tagged or ask your own question.