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
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
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
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.
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!
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
A lot of the slowness being seen in nested partials happens only during development. Switch to production to test.
2