嵌套的 RenderAction 渲染速度非常慢

发布于 2024-11-30 06:36:03 字数 3593 浏览 1 评论 0原文

我有一个 PartialViewResult 操作,它呈现一个我从页面上的 $.ajax 调用调用的 PartialView 。

该 PartialView 还具有针对 VM 中的项目的 foreach 循环,并且在该 PartialView 中我有两个 RenderAction 来渲染另外两个 Partials。

除了渲染速度之外,一切都运行良好。当我注释掉两个嵌套的 RenderAction 时,主要部分视图的渲染速度非常快。当我取消注释它们时,主要部分视图将渲染 3 到 5 秒。即使我删除部分视图中的所有数据以及操作中的所有数据以仅返回空视图,仍然需要 3-5 秒。

不知何故,我的应用程序在渲染这两个部分时遇到问题,即使它们是空的也是如此。

我的代码: 主要操作:

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 秒来渲染整个视图,但没有区别。

我们提出的一种解决方案是完全删除部分内容,将每个部分的虚拟机放入主虚拟机中,并对部分内容中的 HTML 执行相同的操作。但我喜欢在视图上划分特定功能的想法。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

_蜘蛛 2024-12-07 06:36:03

LanFeusT(伟大的名字!!),

RenderAction 会导致性能开销,因为它会形成一个完整的 MVC 循环,而不是仅仅使用当前的控制器上下文。可能会建议您寻求替代方法(例如在视图模型中包含所需的元素)。我也通过艰难的方式发现了这一点,只有在分析我的代码时,我才意识到每个新的 RenderAction 调用所进行的反射量(在 99% 的情况下,这既方便又合适)。

所以我的底线建议是——考虑扩展你的视图模型。

我强烈建议您在 google 上搜索 RenderAction 与 RenderPartial 以获取更多信息。

请参阅:

RenderAction RenderPartial

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文