Which one has the best performance. I have a list array that contains a list of articles. When I list the articles I have a RenderPartial that displays just one article and the parent page goes through a loop of all the articles. The Renderpatial is inside the parentpage loop. What is the best way to go about this?
Loop inside the partial view if you can. Each time you call RenderPartial, the following things happen (courtesy of the MVC source files):
RenderPartial calls RenderPartialInternal
RenderPartialInternal creates a new ViewDataDictionary and a new ViewContext
RenderPartialInternal calls FindPartialView to locate and instantiate a view
FindPartialView searches all registered view engines (normally just one) for the view, using the controller context and view name as keys. Each view engine searches for the view in all the paths it supports, e.g. Views/controller/view.aspx, Views/controllers/view.ascx, Views/Shared/view.aspx, etc. Views can be returned from a memory cache to accelerate this step
The view's Render method is called. I lost track of the inner workings of the Render method of the standard WebFormView at 13 levels down the stack. Render constructs a large numbers of context objects the inner view needs, checks for permissions to run the view, hooks up events for any server controls, re-inspects the Request object to decide what more it needs to do, and so on. After actually rendering the view, it unwinds the context it has created.
Overall, none of these is too bad. It all happens inside the machine's CPU and RAM, which is more than can be said for typical database access that happens in the controller. The process needs to go out to disk only the first time the view is loaded (that can be slow, however; files have to be searched and the view has to be compiled). ASP.NET MVC had to optimize the view rendering process to maintain a high level of performance.
Still, this is quite a bit, and if you can avoid running it multiple times in one request, it will help improve the action method's response times.
One thing that will improve performance of your views by several times
is to set the Debug=false in your web.config (i.e. deploy in Release mode)
In this case MVC engine will cache all views (including partials) and will not try to resolve their location and load them on every attempt to use them.
Related
From what I can tell, MVC seems to treat partial views differently than the main views. It seems as though I can access an object within the main view, but not its child views if that object is going to be disposed once the main controller action returns (see my question here).
I would assume that this is to facilitate async updating of those partial views via AJAX or some other method long after an object in the main controller action is disposed. This makes perfect sense to me.
The way I'm trying to use a partial view right now, I don't need this async updating capability. I COULD just cut out the partial view all together and put it all together, but what I'm looking for is just a way to segment out my views into smaller chunks, rather than having them all in one huge file.
Ideally, I'd like to be able to pass an object from my controller to my view, utilize that object in the view AND any child/sub views, and dispose of the object only after the view and its sub/child views are finished using it.
EDIT - Adding an example
I have a Big Complicated View in a single file. Imagine that each line is actually a larger, more complicated block of view markup and code:
ViewStuff.cshtml
ViewStuff
ViewStuff
MoreViewStuff
MoreViewStuff
MoreViewStuff
ViewStuff
EvenMoreViewStuff
EvenMoreViewStuff
EvenMoreViewStuff
ViewStuff
I would like to break this view into some separate files for convenience and maintenance, effectively extracting portions of it to sub views, like an "extract method" refactoring sort of:
ViewStuff.cshtml
ViewStuff
ViewStuff
RenderPartialViewOf MoreViewStuff
ViewStuff
RenderPartialViewOf EvenMoreViewStuff
ViewStuff
MoreViewStuff.cshtml
MoreViewStuff
MoreViewStuff
MoreViewStuff
EvenMoreViewStuff.cshtml
EvenMoreViewStuff
EvenMoreViewStuff
EvenMoreViewStuff
From what I can tell, partial views seem to be the answer to this, although there seem to be a lot of methods one could use. The problem I'm getting is that my controller is passing in an object to the view which is disposed when the controller action returns.
In the "all in one file" scenario, I can successfully utilize the object to construct the full view, because the whole view is constructed before the method returns and the object is disposed. However, this is not ideal because it means large, long, monolithic view files and potential duplication of portions later on.
In the "multiple files" scenario, the main view can access the object fine, because it hasn't been disposed yet. But the main controller action method returns, disposing the object, before the partial views have gotten it. The result is an error in the partial view, looking for an object which is no longer available.
What I want is a way to construct a complete view made from multiple organized chunks, all before the controller method disposes of my object.
Again, see my other question for some more specific code regarding what I'm doing with this object, the using statement it's in within the controller, etc.
Your problem has nothing to do with Partials. I've already addressed the issue in your other question. The problem also has nothing to do with async, as it's been this way since the very first version of MVC, which did not support async.
You have to pass objects to the view which are not disposed when the method returns.
It seems you're just confused about the difference between partials and child actions.
A partial view is some HTML without a layout. It will inherit the model of it's parent view, unless you pass a different model. This is most likely what you need to use:
#Html.Partial("_MyPartialView")
That's literally all you need. You don't need to add anything at all to your controller.
Now, child actions are different. They're like normal actions, but run within the main request. In other words, they're not accessed through a URL like a normal action would be, but they are nonetheless, completely separate from the main request. They also function as GETs. You don't POST to a child action, which means you can't send along complex data types like an entire model. Their purpose is to allow you render something that doesn't really fit in with the scope of the rest of the page. For example, if your main action and view are tasked with fetching an rendering a single blog post, you might still want to have a side bar that shows other recent posts. With a child action you can fetch the list of recent posts and render that within a view that has its model set for a list of posts, all without affecting the main view.
We are optimising a site and have read about the issue of the initial view lookup taking a long time. Subsequent lookups of the views are then much faster. Mini-profiler shows that a lot of the time is in the initial find view (I know I can use a ~ path to reduce this) and whatever else is done at this stage.
Where is the caching done? How long are view lookups etc cached? Can I see what is cached? Can we do anything to cause it to pre-load so there isn't a delay?
We have many views that are often not visited for hours and I don't want sudden peaks and troughs in performance.
We are using Azure and have a number of web role instances. Can I assume that each web role has its own cache of the view lookup? Can we centralise the caching so that it only occurs once per application?
Also I read MVC4 is faster at finding views? Does anyone have any figures?
The default cache is 15min and is stored in the HttpContext.Cache, this is all managed by the System.Web.Mvc.DefaultViewLocationCache class. Since this uses standard ASP.NET caching you could use a custom cache provider that gets its cache from WAZ AppFabric Cache or the new caching preview (there is one on NuGet: http://nuget.org/packages/Glav.CacheAdapter). Using a shared cache will make sure that only 1 instance needs to do the work of resolving the view. Or you could go and build your own cache provider.
Running your application in release mode, clearing unneeded view engines, writing the exact path instead of simply calling View, ... are all ways to speed up the view lookup process. Read more about it here:
http://samsaffron.com/archive/2011/08/16/Oh+view+where+are+thou+finding+views+in+ASPNET+MVC3+
http://blogs.msdn.com/b/marcinon/archive/2011/08/16/optimizing-mvc-view-lookup-performance.aspx
You can pre-load the view locations by adding a key for each view to the cache. You should format it as follows (where this is the current VirtualPathProviderViewEngine):
string.Format((IFormatProvider) CultureInfo.InvariantCulture, ":ViewCacheEntry:{0}:{1}:{2}:{3}:{4}:", (object) this.GetType().AssemblyQualifiedName, (object) prefix, (object) name, (object) controllerName, (object) areaName);
I don't have any figures if MVC4 is faster, but it looks like the DefaultViewLocationCache code is the same as for MVC3.
To increase my cachetime to 24 hours I used the following in the Global.asax
var viewEngine = new RazorViewEngine
{ViewLocationCache = new DefaultViewLocationCache(TimeSpan.FromHours(24))};
//Only allow Razor view to improve for performance
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(viewEngine);
Also this article ASP.NET MVC Performance Issues with Render Partial was also interesting.
Will look at writing my own ViewLocationCache to take advantage of shared Azure caching.
First of all, I have been a php programmer for a long time and I am a mvc programmer newly. I did a few minor web sites that each have one or two controller at most. But I've started a website that will be very major web site. There will be a lot of data to pass to views.
Now, normally I try to use model approach every time instead of ViewBag or ViewData approach. If the view demands more data, then I change the model class and then recompile the project. Especially, if the topic is an index page, the data to pass to the index's view changes every time. In a big web site, I'll use a lot of partial view that uses different models. So every time, I will have to change the index's model to support those partial views in the index view. if I add a new partial view into index view, I have to add the partial's model into the index's model.
I implement an IndexModel class for an index view every time when I start a website. Then I add properties to this model every time when I add a new partial view to the index.
Now is this a correct approach or should I use ViewBag or ViewData for partials' models. I think the real question is when we should use the model approach and when we shouldn't...
If you share your experiences, I would be grateful.
The MVC approach you should use always, especially for simple sites, it's save your time and make application more understandable.
If you write something larger than two pages, you need to use MVVM pattern (growth of MVC), in that case you will escape from using "partial models" with ViewModels.
Model must contain only busines logic.
Be better if you will always use ViewModel (not a Model) for returning data from a view and pass it to view, because it provides some safety.
For facilitate the procedure of copy data from Models to ViewModels use the things like AutoMaper and EmitMapper.
ViewBag and ViewData you should use only for additional data's like item colections for DropDown, or some view-text like page title.
One more advantage of MVVM pattern is better testability. If you write and support really hugh site you may write tests for some responsible parts of code.
For more details you can look at google - MVVM, ASP-MVC.
If i something not understad in you question or miss, write it in the comment ("add comment" ref).
I personally prefer to keep my sites consistant and always use Model + Viewmodel (no matter how big the site is) despite the extra work (which isn't much anyway).
It helps with maintainability. I know where and how everything is stored and coded into the site.
We have a dashboard-style application with lots of individual bits of the screen that load asynchronously. Each of these bits really makes sense as its own action on the page's controller. However, the data will load more quickly if we reduce the number of http requests to 1. I'm considering creating an action that just returns a combination of results from several smaller actions, such that the web client can GET the actions separately or together. However, this seems like a hand-rolled solution to a common problem, so I'm wondering if there's built-in support for agglomerating actions in this way that I don't know about. Anybody?
In your core view, you can use the Html.RenderAction() method to render completely separate actions from another action.
Why don't you just use ViewModel containing all data needed for your dashboard and then create several partial views, feed them with data from ViewModel?
I have also an dashboard in my project, I did it this way and I am happy with the solution. I have DashboardController and its Index action just takes ViewModel (which aggregates all necesary data) and sends it to View. In that View, I have several partial views (each of them needs its own model) and I pass them data from my ViewModel. Inside that partial view are then references to specific actions (like CRUD for specific models).
When you do it this way, you can easily create partial views for specific models (Task, Project, User .. in my case). And then just use them as a pieces in your final layout. My ViewModel contains collections of Tasks, Projects and Users which I then simply pass to matching partial views.
At top there is some most useful info about foo.
Between horizontal lines there is some immediate actions, if they are available, to perform on/with foo.
And below is thing that bothers me. There goes tabbed, detailed information about foo.
Those tabs can hold some actions too and can be quite sovereign.
So the question is - how to properly structure this thing (what should be controllers, actions, how do they talk to each other) in order to avoid unnecessary hussle?
I'm confused cause those tabs below are like a separate island.
In model - there's that strange thing: 1 on 1 relation. It's like there's a Contest (Foo), and Participant. Tabs are detailed description of Participant.
Currently I've modeled them both as aggregate roots. But it might be a wrong choice.
So - if there are two roots, it seems natural if both of them got controllers and Contest isn't really responsible to hold all data.
It seems that sub actions would be the way to go, but I foresee some complexity. When tabs will hold some actions, they will need to know how to redirect back to Contest details and how to pass info how to render correct tab. This coupling I would like to avoid but it seems there's no way to do that.
I can think of a couple options for those tabs ... which one makes sense probably depends on what your Model looks like, how you retrieve data and, to some degree, what the rest of your app looks like.
Option 1. Partial Views with RenderPartial(). Each tab is a partial view that renders some portion of your Model. For example, you would have a FinancialInformation.aspx partial view that renders Model.FinancialInformation.
Option 2a. Sub Actions with RenderAction(). Similar to above except that each tab is responsible for pulling its own data by calling an action method either on the same controller or more likely another controller that specializes in that information.
Option 2b. Same as 2a except that the tabs are rendered on demand using AJAX.
I should point out that none of these options is mutually exclusive. You might use option 1 (RenderPartial()) for the first two tabs since that data is inherently part of your model. And you might use option 2 (RenderAction()) for the other two tabs because, for example, you might have a ChartController the specializes in rendering charts ...