In keeping with the DRY-principle I try to use partials as soon as I am repeating a particular pattern more than once or twice. As a result, some of my views consist of ten or more different partials. I am worried that this might have a negative effect on the overall performance. Some programming books compare the use of partials with the use of methods. So should I use the same rationale to determine when to use them?
What is the best practice regarding size and quantity of partials in a Rails project?
I like your practice already: Once you've repeated view code twice, refactor it out to a partial. Tim's right that you can speed it up as necessary after it's been profiled and after it's been proven necessary.
Here is my one caveat: If you work with professional designers who handle the views, it may be easier over the long term to have rather repetitive view code. Some people have a hard time searching through partials and "seeing" how they all fit together. I've found it easier with those people to let them manage the whole shebang and update more than one file if they need to. Optimal? Not to us as programmers, but designers are more often used to seeing most of the HTML in one or three files rather than 20. :)
Remember the rules of optimization!
If, once your application is complete, your views are too slow, use something like New Relic to find out where the slowdown is occurring. There are a lot of places that might be, but it's unlikely to be in your partials.
Related
At my new job, I was given some MVC work. There is only one controller with nine action methods(6 are for ajax rendering) . The page was bit large, so I divided it into small your controls and used render partial to render them. Some user controls were being render through ajax also. Most of the controls are not more like foreach loops and rendering some data from tables, not more 10-15 lines. The main index page passes model to all the controls. My main page looked very clean and easy to maintain.
But my team members are saying, I should put everything in the main page rather than building small controls. Their point is number of files will be a lot, if we start creating controls like this. Also they say if we are not reusing these controls somewhere else there is no point creating them separately.
I would like to know what is better approach for this kind of scenario. Any good links which can help us to understand things better, or any book we can read to clarify our questions.
Help will be appreciated.
Regards
Parminder
As a preface to my answer, let me mention the important value of maintainability. Software evolves over time... and must change to fit the need of the application.
Maintainability in code does not magically appear... Sacrifices (with a touch of paranoia sometimes) must be made in your coding style now, to have the flexibility you'd like in the future.
There may a large page in your project. Some may say that if it works, no need to fix it. But that's looking at it from a short term perspective. You may need some of those UI interfaces in other places in the future. What some persons may do (rather than make partials) is copy that code in the places where they need it - thus causing the same bloat over time that they were trying to avoid.
If you're on the project in the long haul, you'll more fully appreciate the need for flexibility over time. You can see that there are patterns that you'll want to re-use.
My suggestion then: Partials and controls are good things... they are good investments for your ease in the future. If you forecast reusability, that's a good sign for using them.
But use them sparingly. Don't micromanage everything on a page. Some things may be itching to be 'component-ized' but sometimes it's best to SSFL (Save some for later). Like everything in life, balance is important.
Having clean concise code is the way to go. Your code will be alot more readable if you utilize :
sections
templates
partial views
Just remember its always easier to navigate folder structure than to read 100's - 1000's of lines of code.
I recommend watching "Putting your controllers on a diet" by Jimmy Bogard.
Also read "Fat Controllers" by Ian Cooper.
these two links will give you a good idea on how to structure your MVC apps.
I am trying to optimize my code as much as possible. I use a lot of partial files like this:
#if (Model.PageMeta.Sidebar == PageMetaSidebar.Small) { Html.RenderPartial("_SmallSidebar"); }
..
..
..
Can someone tell me if there is a performance overhead with this. I understand that Razor views are compiled. Is it the case that when the page is displays there is another disk read to get the data for each of the partial files that I use. If that's the case then how much additional overhead could I expect with for example 5 RenderPartials on my layout page.
There will be no noticable performance hit at all here as the partials are just pulled in on the asp.net web server before streaming the resultant HTML back to the browser. This is not an expensive disk read to do and won't appear any slower than if it was a single cshtml. Obviously partials should be used if the same partial view is reused in many views. If only used in a single view then it's just a matter of clarity splitting it into a separate partials to separate parts of your model into different views.
Note you can also just use:
#Html.Partial("YourPartial")
rather than using RenderPartial. This will look in the local view folder then in shared if not found.
I don't think using RenderPartial ~5 times is going to have a significant enough impact to design your pages poorly. If it makes sense to pull the logic out (makes the page cleaner, used by multiple views, etc.) then do it. If you notice significant performance issues then you should look at them at that time, but don't prematurely optimize and create a poor design because you THINK it might slow something down.
If you like to get a better understanding of potential performance hits you might want to play around with the mvc-mini-profiler.
Please note though that I'm not advocating pre-mature optimization. However, using profiling tools might give you a better understanding of potential bottlenecks, thus helping you avoid them in the future.
Is it correct to use partial views for the SOLE purpose of breaking down a more complicated view into separate chunks and therefore making it more readable?
It probably seems a silly question but the reason I ask is that everything I've read about using partial views involves a piece of the UI being re-used in multiple places. In my case the piece of UI being put into the partial view is only used in one place. It is therefore done solely for readability, but I'm not sure if the performance impact of this may outweight the increased readability. Thoughts?
Whilst this is correct there are more uses.
Reusability
Ability to pass pack rendered html
from your controller so you can
append the partial view to the bottom
of containers. Great for jQuery
async calls
Seperation of concerns
Gives developers the ability to work
on different sections of a page w/out
getting in each others way.
Just to name a few.
I think that you shouldn't be worried about performance until it is a real problem, but you should be worried about your code from the first moment. I usually use partial views to simplify the logic or the structure of my views, as you are wanting to do.
Sure, that's an okay use for them. If it keeps the page organized so it's easier to maintain, I think it's fine.
Also, if I'm using caching, I find it easier to have my:
cache "this" do
# render partial
end
I find it easier to read and keep track of things, especially on an overview or dashboard page where there are lots of different parts of the pages that you're including.
I tend to be a bit more conservative. I only use a partial view when I know I'll need to reuse the code or I have multiple complex objects in ViewData that need to be displayed.
There's no right or wrong way here but I have worked on projects where there are a ton of partial views to make things "more simple" and I end up spending forever trying to track down where all the partials are (controller/action folder, shared folder, or elsewhere).
One thing about my approach though is if you have even the slightest thought that the view code may be reused down the line as the project changes use a partial. It will save a bunch of time down the road.
I veto any large and complex view in our projects. Instead, we use RenderAction to extract those pieces of code into smaller chunks/parts. I blogged about it here:
http://eduncan911.com/blog/html-renderaction-for-asp-net-mvc-1-0.aspx
Basically, you move that logic and/or parts into Controllers.
Or, if you are just talking html - then yes, breaking down a view into RenderPartials works too.
So DRYing up code is supposed to be good thing right? There was a situation in one of the projects I was working on where there were certain models/entities that were more-or-less the same except the context in which they were being used. That is, Every such entity had a title, descriptions, tags, a user_id etc and some other attributes. Hence their CRUD actions in their respective controller looked pretty similar.
My manager argued that its repetition of code and needs to be DRYed up. Hence he came up with CRUD ruby module that when included took care of CRUD actions for the controllers of all these entities. But eventually, Simplicity was compromised. The code lost readability as every "thing" was named "object". Debugging became difficult and the whole point of DRYing up the code was lost.
This was just one case. There are several of them where DRYing up resulted in complex, hard-to-debug code. So the question is, when do we stop DRYing up the code? Because not every time you realize the code has lost simplicity (And often the code author never realizes the simplicity of code is lost). Also, if we have to choose between simplicity and DRYed code, what should choose, if at all there comes a situation where you could get only either of them.
From what I understand, if DRYing up code is causing loss of simplicity, we are doing something terribly wrong. I think, we should be DRYing up code that is repeated and has single responsibility. If the code responsibilities are different and/or the abstraction of entities cannot be named, we are not repeating code. The code pattern might be repeated but its a different code altogether with a responsibilty of its own. If DRYing is resulting into vague code, you are probably trying to DRY up code with different responsibilities that have a similar pattern which is not really a good practice. DRYing should enhance the simplicity, not suppress it.
If you are following REST, then yes, the controllers will be very similar and largely boilerplate. I agree with your manager that it's a problem.
It sounds though like he came up with a suboptimal solution. For a better one, check out Jose Valim's inherited_resources plugin that is being incorporated into Rails 3.
Readability and Maintainability are the two most important features of good code. Unfortunately, a compromise has to be made sometimes. It's a balance question and not everyone is going to agree.
Myself, I lean towards your point of view as well. I would rather have some apparent repetition if it means the code is easier to understand.
As for the 'debugging' problem, I am in the habit when I create such a 'base class' to include a supplementary field. This field is a simple string which identify the most derived class (and is thus passed from Constructor to Constructor). Then each message is going to print this field + the object id "realtype[id]" and everything is suddenly much easier to debug.
Now on to DRY.
There are two things to DRY:
building a hierarchy
using generic code
The first point should now be well understood. A hierarchy of class means a IS-A relationship. If two classes have similar behavior but are otherwise functionally unrelated, then they SHOULD NOT be part of the same hierarchy. It only confuses the poor maintainer and hurts readability.
The second point can be used much more often, especially with scripting languages. For the precedent example, I would argue that instead of having a hierarchy of classes, you could simply define generic methods that would take different classes (modeling different business) and treat them uniformly. This way you avoid repetition (DRY) yet you do not sacrifice readability (imho).
My 2 cts.
If someone every told me--with a straight face--that my code needed DRYing, I would probably take that as a sign that anything else they were going to do was going to be really far-fetched and for-the-sake-of-it.
That having been said, there is also a difference between simplicity in writing code (laziness) and simplicity in the code itself (elegance). I agree, though, that there is a balance. I had this situation myself one particular time (in PHP, but oh how it reminds me of your dilemma):
$checked = ($somevariable) ? "checked=\"checked\"" :"";
echo "<input type="radio" $disabled_checked />";
$checked = ($someothervariable) ? "checked=\"checked\"" :"";
echo "<input type="radio" $checked />";
This isn't even a very good example of what I was dealing with. Essentially, because it's a radio input, both inputs needed a some way of knowing which was to be bubbled in. I knew it had what your boss might call "wetness" issues, so I racked my head trying to come up with some solution that would be graceful and to the point. Finally I showed it to a senior developer and he said "No, it's all in order, it does what it needs to. It's only one extra line."
I felt a relief at being reminded that I was hurting my project more then helping by worrying over this, but at the same time, I'm still disappointed that he was so casual about a fundamental principle (as though it wasn't one of his, though I'm sure it is).
So while I agree, your manager probably was doing something just for the sake of doing it, it is only when we strive to come up with the better methods and approaches that we get better languages like Ruby and Python and cooler libraries like Jquery.
Basically, what if next week you suddenly had 70 things instead of 2? If your boss's objects make that a snap, he was right. If it's the same amount of trouble (in the code or in the execution), he was wrong. But that doesn't mean there isn't a better answer then keeping it simple because it's only a couple of things.
The aim of the DRY principle is to help increase the "quality" of the code.
If the changes aren't improving the quality of the code, it is time to stop.
The ability to judge this comes with experience. As requirements change, the most appropriate way to refactor the code also changes, so it's impossible to have everything ideal - at least you need to freeze the requirements first.
Minimising the size of the code should generally not be a consideration in the quality unless you are codegolfing, so don't DRY when the only purpose is to reduce the size of the code.
Complicated tricks can do more harm than good.
A key reason for applying DRY to improve maintainability is to ensure that when a code change is necessary, that change only needs to be made in one place, thus avoiding the risk that it doesn't get changed everywhere that needs it.
But I'm not telling the whole story:
This interview with Dave Thomas has DT saying:
DRY says that every piece of system
knowledge should have one
authoritative, unambiguous
representation.
The first time I saw "DRY" was in The Pragmatic Programmer so I'm inclined to go with Dave on this.
There's another article worth reading here
But DRY is a principle, not a rule: the better we understand the principle, the more able we should be to recognise situations where it should be applied.
(And finally, I think I'd want a little more than "more-or-less the same" before I started "DRY"ing that code: if I could see a clear way in which the two things might diverge in the future then I'd be inclined to leave them alone).
For me, duplicated code is a smell that can have multiple origins:
Missing variables (introduce variable).
Missing methods (push expression into a method).
Feature envy (push behaviour down into the envied class).
Over-generalization (break up generic class into specific concrete classes).
Insufficient abstraction (push attributes and behaviour down into new class).
This list is probably incomplete. Consider it a starting point.
When you find duplication, think about what problem it's symptomatic of. Then take a stab at addressing that problem. When you're done, consider the readability of the new code. If it has deteriorated, you may be in one of these positions:
You misidentified the problem at the root of the duplication (revert, rethink, try again).
The duplication is a necessary trade-off (revert your change and live with it).
Your software is necessarily complex (commit your change and live with it).
Consider posting example code along with questions like this, if possible. They provide something concrete to work around. And remember, a lot of this stuff is very subjective.
Can I use partials as much as I want or do I have to restrain myself to avoid bringing my views to a crawl under much traffic?
There's an obvious overhead using partial but this isn't something you should probably worry about.
Partials are files. When you render an action without partials, your action "costs" 1 file (that's not totally true, but this is to simplify the explanation).
If your action renders 4 partials, you end up with a cost of 5. This means, you have 4 additional IO calls and the real cost for each call depends on your server load, server performances and so on.
But does this cost matter? In my experience, for the 99% of times no. Also noteworthy, the benefits of using partials in terms of code readability and maintainability usually are worth the choice.
If performances must be a key feature, you should probably look for speed and improvements elsewhere.
Remember: Ruby is not a super-fast programming language and code expressiveness always took the first place in favor of performances. Rails implicitly agree to this convention, albeit the Rails team has always focused on performances (and Rails 3 it's the practical demonstration there's always place for improvements)
That said, you can safely use partials and reduce the application overhead with some clever caching mechanism. For example, you can place collection rendering within a cache block so that a render collection statement will be executed only once then your app will simply load 1 cache file instead of 10 un-cached partials.
One of the most sneak errors I made many times at the beginning was to worry about performances in the wrong way, that said, without actually running benchmarks. I remember once when I was trying to drop one single database query in favor of an hard coded hash because "the query costs", without realizing there was an other stupid query that was loading an entire table collection without the include statement, that resulted in running the second query 3 times slower.
So, if you really care about performance, you probably shouldn't avoid using partials but instead make sure you are taking advantage of all the other features Rails provides you to scale your application.