【问题标题】:Does using a display template with IEnumerable cause slowness?使用带有 IEnumerable 的显示模板会导致速度变慢吗?
【发布时间】:2015-03-26 13:58:31
【问题描述】:

因此,我决定从这里看到的关于在使用 IEnumerable<T> 时使用显示模板的“正确”方法的大量帖子中获得一些乐趣。

我有一个正在创建的表,我为行创建了一个单独的显示模板。本例中的模型是IEnumerable<PartTest>

<table>
    <thead>
        <tr>
            <th>Job Number</th>
            <th>Part Number</th>
            <th>Tester</th>
            <th>Pass / Fail</th>
            <th>Test Date</th>
        </tr>
    </thead>
    <tbody>
        @if (Model.Any())
        {
            using (MiniProfiler.Current.Step("Render Table"))
            {
                Html.DisplayFor(model => model);
            }
        }
        else
        { 
            <tr>
                <td colspan="5">No results - update search fields</td>
            </tr>
        }
    </tbody>
</table>

模板:

@model PartTest

<tr>
    <td>@Html.DisplayFor(model => model.JobNumber)</td>
    <td>@Html.DisplayFor(model => model.PartNumber)</td>
    <td>@Html.DisplayFor(model => model.Tester)</td>
    <td>
        @if (Model.IsPassing)
        {
            <div class="label label-success label-small">Passed</div>
        }
        else
        {
            <div class="label label-danger label-small">Failed</div>
        }
    </td>
    <td>@Html.DisplayFor(model => model.TestDate)</td>
</tr>

我使用的是区域,所以路径是 ~/Areas/PartsTesting/Views/Shared/PartTest.cshtml。 当我运行它时,它运行得非常慢。我的意思是有时 10-15 秒。数据集并不离谱,但有时它可能超过 100 多个项目,在这种情况下我提供了一个滚动条,但我不认为渲染 100 行会导致这种缓慢。

当我切换到仅手动迭代 for 循环中的项目并一起跳过显示模板时,它在约 40 毫秒内运行了 200 多个项目。这里发生了什么?为什么我使用显示模板时会这么慢(从我读到的内容是为 MVC 编写“更好”的方式)?

【问题讨论】:

  • 我认为它会在循环的每次迭代中查找文件。将调试设置为 false
  • 这很有趣。当我关闭调试时,速度是可比的。我不确定时间差异是否可以容忍,但可以保证使用显示模板。每次运行等待可能超过 20 秒并不是我在测试时可以接受的时间。我喜欢使用显示模板的概念,但不以浪费时间为代价。
  • 我个人也不喜欢模板。我建议你改用部分视图
  • @Ewan 如果你想把它写下来作为答案,我会接受的。
  • @Ewan:显示/编辑器模板部分视图。使用 Html.DisplayForHtml.Partial 之类的东西在性能方面绝对没有区别,因为它们本质上做的是相同的事情:渲染局部视图。

标签: c# asp.net-mvc performance templates


【解决方案1】:

http://forums.asp.net/t/1614418.aspx?+Html+DisplayFor+item+item+Property+extremely+slow中所述

“当调试打开时,我们不会缓存从视图名称到视图文件的映射”

“设置 debug=true 会禁用优化的代码路径以协助调试。在您的特定情况下,它会禁用视图位置缓存。”

似乎每次调用 Html.DisplayFor 都会搜索匹配的模板。显然这个文件操作,伴随着所有的检查文件是否存在等等是相当慢的。

将 debug 设置为 false 将优化此问题。

虽然个人... 我建议您尝试使用 Html.RenderPartial 而不是 Html.DisplayFor。

虽然,专家意见是这将遭受同样的问题。我一直讨厌模板,认为它们是“老派”

【讨论】:

  • 重要的是要提到Html.RenderPartial 只有在部分实际同时处理整个可枚举时才会更有效率。确实,显示模板的本质是它们只处理单个项目,因此必须为可枚举中的每个项目呈现模板。为 for 循环中的每个项目调用 Html.RenderPartial 将是完全相同的场景。
  • 我相信你的话,虽然它显然略有不同,因为你指定了视图名称,它寻找视图而不是模板等。也许 OP 可以运行一个快速测试?
  • 这是我其他评论的重点。这两种观点。显示模板只是部分视图。它只是遵循某些命名和位置约定以使其与DisplayFor一起使用。
  • 好的,我测试过了。两者对我来说都同样快 debug=true mvc 5
  • 我切换到使用 for 循环,只是将显示模板移动到父视图中。我最初根据其他 SO 用户的建议进行了尝试,发现在这种情况下完全是浪费时间。它对其他事情很有用,但这不是其中之一。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-27
  • 1970-01-01
  • 2022-01-27
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多