嵌套的RenderAction渲染非常缓慢。

7
我有一个PartialViewResult操作,它呈现了我在页面上从$.ajax调用的PartialView。这个PartialView还有一个foreach循环用于VM中的项目,并且在这个PartialView中,我有两个RenderAction呈现了另外两个PartialView。
一切都很好,除了它呈现的速度。当我注释掉这两个嵌套的RenderAction时,主要的PartialView呈现非常快。当我取消注释时,主要的PartialView需要3到5秒才能呈现。即使我从PartialView和操作中删除所有数据,只返回一个空视图,仍然需要3-5秒。
不知何故,我的应用程序在呈现这两个PartialView时出现问题,即使它们是空的。
我的代码: 主要的操作:
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
    });
}

它相关的ViewModel:
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; }
}

我的主要 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>    
}

如果需要,我可以为“ShowFlags”和“CheckTrackStatus”添加操作。但是,正如我所提到的,即使我从动作和视图中删除所有代码,渲染仍然需要3-5秒钟来呈现整个视图,没有任何区别。
我们想出的一个解决方案是完全删除部分内容,将每个部分的VM放在主VM中,并对部分HTML执行相同的操作。但我喜欢在视图上划分特定的功能的想法。
1个回答

3

LanFeusT(很棒的名字!!),

RenderAction会导致性能开销,因为它会进行完整的MVC周期,而不仅仅是使用当前控制器上下文。建议您寻找替代方法(例如在viewModel中包含所需的元素)。我也是通过对代码进行分析才发现每个新的RenderAction调用都需要进行大量反射(在99%的情况下既方便又适当)。

所以我的底线建议-考虑扩展您的viewModel。

我建议您谷歌RenderAction vs RenderPartial以获取更多信息..

请参见:

RenderAction RenderPartial


好的,这个方法确实奏效了。我并没有真正期望它能够起作用,或者至少不会有那么大的差异。但是将嵌套的虚拟机传递给主虚拟机,并仅使用RenderPartial,将加载时间从3-5秒降低到500-600毫秒。谢谢! - LanFeusT
很酷,我也经历了和你一样的头发被拔的过程,但现在我非常清楚何时使用RA vs RP。很高兴这有所改变(而且重构起来如此简单)。 - jim tollan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接