Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested RenderAction are rendered very slowly

I have an PartialViewResult action which renders a PartialView that I call from a $.ajax call on the page.

That PartialView also has a foreach loop for the items in the VM and within that PartialView I have two RenderAction that render two other Partials.

It all works fine, except for the speed at which it's rendered. When I comment out the two nested RenderAction, the main partial view renders extremely fast. When I uncomment them, the main partial view renders between 3 to 5 seconds. Even if I remove all data from the partial views and all data from the actions to only return an empty view, it still takes 3-5 seconds.

Somehow, my app is having problems rendering these two partials even when they're empty.

My code: Main action:

public PartialViewResult MyTasks(int milestoneId, int currentPage = 1)
{
    var mergedTasks = new List<MergedTask>();   
    var TrackingTeams = _TrackingTeams.GetAll().ToList();
    var pagingInfo = new PagingInfo() {CurrentPage = currentPage, ItemsPerPage = 10, TotalItems = _TrackingTeams.GetAll().Count() };                                                                     
    mergedTasks.AddRange(from TrackingTeam in TrackingTeams
                       let task = allTasks.Single(x=>x.TestId == (int)TrackingTeam.TrackingTask.TestId)
                       select new MergedTask()
                       {                           
                           Summary = TrackingTeam.TrackingTask.Description,
                           InternalId = task.Id,
                           DevTrackingTask = TrackingTeam.TrackingTask,
                           LastUpdate = task.DateModified
                       });

    return PartialView(new DevTrackingTaskViewModel
    {
        MergedTasks = mergedTasks,
        Category = _categories.GetById(categoryId),
        PagingInfo = pagingInfo
    });
}

The ViewModel associated with it:

public class TrackingTaskViewModel
{
    public List<MergedTask> MergedTasks { get; set; }
    public int CountTasks { get; set; }
    public PagingInfo PagingInfo { get; set; }
    public Category Category { get; set; }
}

public class MergedTask
{
    public int InternalId { get; set; }
    public string Summary { get; set; }
    public TrackingTask TrackingTask { get; set; }
    public DateTime LastUpdate { get; set; }
}

My main PartialView:

@foreach (var item in Model.MergedTasks)
{
    <script type="text/javascript">
        $(document).ready(function () {
            $("#TrackingTask@(item.TrackingTask.Id)").hover(function () {
                if ($("#snapshotFixerForTrackTask@(item.TrackingTask.Id)").length == 1) {
                    $("#expandTrackingTaskForTask@(item.TrackingTask.Id)").removeClass("hide");
                }
                else {
                    $("#expandTrackingTaskForTask@(item.TrackingTask.Id)").toggleClass("hide");
                }
            });
        });
    </script>

    <div class="TrackingTaskDiv" id="TrackingTask@(item.TrackingTask.Id)">
        <div class="TrackingContainer">
            <div id="flagsForTrackingTask@(item.TrackingTask.Id)" class="flags">
               @{Html.RenderAction("ShowFlags", "Task", new { trackingid = item.TrackingTask.Id });}
            </div>

            <div id="TestStatusForTrackTask@(item.TrackingTask.Id)" class="TestStatusWrapper">
                @{Html.RenderAction("CheckTrackStatus", "Task", new { trackingid = item.TrackingTask.Id });} 
            </div>
        </div>
        <div id="expandTrackingTaskForTask@(item.TrackingTask.Id)" class="expandTrackingTask collapsed hide"></div>
    </div>    
}

I can paste in the Action for the "ShowFlags" and "CheckTrackStatus" if needed. But as I mentionned even if I remove all the code from the action and the view the rendering still takes 3-5 seconds to render the whole view, there's no difference.

One solution we came up with would be to remove the partials altogether, put the VM of each partial inside the main VM and do the same for the HTML in the partials. But I like the idea of compartmentalizing specific features on a view.

like image 600
LanFeusT Avatar asked Aug 17 '11 21:08

LanFeusT


People also ask

What is the difference between RenderPartial and RenderAction?

RenderPartial is used to display a reusable part of within the same controller and RenderAction render an action from any controller. They both render the Html and doesn't provide a String for output.

What is the use of RenderAction in MVC?

RenderAction(HtmlHelper, String, String, RouteValueDictionary) Invokes the specified child action method using the specified parameters and controller name and renders the result inline in the parent view.

What is the difference between RenderPartial and partial in MVC?

The primary difference between the two methods is that Partial generates the HTML from the View and returns it to the View to be incorporated into the page. RenderPartial, on the other hand, doesn't return anything and, instead, adds its HTML directly to the Response object's output.

What is the difference between HTML partial vs HTML RenderPartial & HTML action vs HTML RenderAction?

Render vs Action partialRenderPartial will render the view on the same controller. But RenderAction will execute the action method , then builds a model and returns a view result.


1 Answers

LanFeusT (great name!!),

RenderAction will cause a performance overhead as it makes a complete MVC cycle, rather than just using the current controller context. you may be advised to seek an alternative approach (such as including the required elements in your viewModel). i found this out the hard way as well and it was only when profiling my code that i appreciated the amount of reflection going on for each new RenderAction call (which in 99% of circumstances is both convenient and appropriate).

So my bottom line advice - look at extending your viewmodel.

I urge you to google RenderAction vs RenderPartial for further info..

see:

RenderAction RenderPartial

like image 78
jim tollan Avatar answered Sep 26 '22 00:09

jim tollan