【问题标题】:Performance profiling of Razor viewsRazor 视图的性能分析
【发布时间】:2018-08-11 12:42:16
【问题描述】:

我正在处理一个项目,我们在其中呈现一种文章列表,其中包含许多可选的图像和文本属性,并且全部采用“花哨”的非表格布局,以适应现有/缺失的属性并添加一些随机性。客户想要一个随意的外观,我们最终在每个级别上都有一棵深度为 4 和 3-10 的剃刀模板树。每个模板都非常简单,没有“魔法”发生。

在负载测试期间,我们发现对于大型文章列表,我们在视图渲染中存在性能问题。渲染 5 篇文章需要 20ms,但渲染 60 篇需要 1s。

有没有一种聪明的方法来衡量每个模板的渲染持续时间?我想避免在任何地方手动添加秒表。有没有框架方式?是否有关于如何调试此类问题的建议?我找不到任何东西。

【问题讨论】:

  • 你可以试试 Stack Overflow 自己的MiniProfiler。虽然我不确定这是否会对您的情况有所帮助。

标签: c# performance razor asp.net-core .net-core


【解决方案1】:

自己刚刚找到了一个好的解决方案:

public class RazorPerformanceDiagnosticListener
{
    private readonly IDictionary<string, TemplatePerformanceHolder> _timers = new ConcurrentDictionary<string, TemplatePerformanceHolder>();

    [DiagnosticName("Microsoft.AspNetCore.Mvc.Razor.BeginInstrumentationContext")]
    public virtual void OnBeginInstrumentationContext(HttpContext httpContext, string path, int position, int length, bool isLiteral)
    {
        if (_timers.ContainsKey(path))
        {
            _timers[path].ContextDepth++;
        }
        else
        {
            _timers[path] = new TemplatePerformanceHolder(){ContextDepth = 1, Stopwatch = Stopwatch.StartNew() };
        }
    }

    [DiagnosticName("Microsoft.AspNetCore.Mvc.Razor.EndInstrumentationContext")]
    public virtual void OnEndInstrumentationContext(HttpContext httpContext, string path)
    {
        _timers[path].ContextDepth--;

        if (_timers[path].ContextDepth == 0)
        {
            _timers[path].Stopwatch.Stop();
            //log _timers[path].Stopwatch.Elapsed
            _timers.Remove(path);
        }
    }
}

public class TemplatePerformanceHolder
{
    public Stopwatch Stopwatch;
    public int ContextDepth;
}

在 Startup.cs 中

using System.Diagnostics;

public void Configure(DiagnosticListener diagnosticListener)
{
    diagnosticListener.SubscribeWithAdapter(new RazorPerformanceDiagnosticListener());
}

如果您想知道为什么需要跟踪此上下文深度:这些 BeginInstrumentationContext 事件在一个 razor 模板中被多次触发(EndInstrumentationContext 也是如此),因此每个模板都有一个堆栈。

另外请记住,此代码会遇到并发请求(或并行模板渲染)的问题。要解决这个问题,您需要将 HttpContext 以及可能的线程 id 作为 Dictionary 键的一部分。但我不需要“生产就绪”代码,所以要小心。

基于this

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    相关资源
    最近更新 更多