到Url.Action首先调用页面上的慢(First call to Url.Action on a

2019-07-30 22:20发布

我有一个非常简单的ASP.MVC视图性能问题。

这是一个日志上,应该是差不多的即时页面,但需要大约半秒。

经过大量挖它看起来像这个问题是第一次调用的Url.Action -它采取围绕450ms(根据MiniProfiler ),但似乎出奇的慢。

对后续调用Url.Action正在<1ms的,这是比较符合我的期望。

这是我一贯的使用是否Url.Action("action", "controller")Url.Action("action")但似乎并没有,如果我使用发生Url.Content("~/controller/action") 。 当我把这个也恰好Html.BeginForm("action")

没有人有任何的想法是什么引起的?

一挖成源表明, RouteCollection.GetVirtualPath可能是罪魁祸首,因为这是常见的两种Url.ActionHtml.BeginForm 。 然而,想必是使用所有的地方? 我的意思是,½第二是过于缓慢。

我有20个左右的定制路由(这是一个相当大的应用程序有一些旧的WebForms页)但即使是这样的时代似乎过于缓慢。

任何想法如何解决呢?

Answer 1:

发现问题,并且它与路由表(欢呼基里尔)。

基本上我们有很多途径,看起来是这样的:

string[] controllers = GetListOfValidControllers();

routes.MapRoute(
    name: GetRouteName(),
    url: subfolder + "/{controller}/{action}/{id}",
    defaults: new { action = "Index", id = UrlParameter.Optional },
    constraints: new { controller = "(" + string.Join("|", controllers) + ")" });

事实证明, 在正则表达式检查是非常缓慢的 ,痛苦的缓慢。 所以我的实现替换它IRouteConstraint ,只是会针对一个HashSet来代替。

然后,我改变了地图的路线呼叫:

routes.MapRoute(
    name: GetRouteName(),
    url: subfolder + "/{controller}/{action}/{id}",
    defaults: new { action = "Index", id = UrlParameter.Optional },
    constraints: new { controller = new HashSetConstraint(controllers) });

我还使用了该链接的文章中提到RegexConstraint任何东西更复杂-包括很多像这样的电话(因为我们有传统的WebForm页):

routes.IgnoreRoute(
    url: "{*allaspx}", 
    constraints: new { allaspx = new RegexConstraint( @".*\.as[pmh]x(/.*)?") });

这两个简单的变化完全解决问题; Url.ActionHtml.BeginForm现在需要大量的时间可以忽略不计(甚至有很多路线)。



Answer 2:

在我看来,你的问题正在编制的意见。 你需要向预编译生成的观点和这一问题将消失。 这里的细节



Answer 3:

    public class RegexConstraint : IRouteConstraint, IEquatable<RegexConstraint>
     {
    Regex regex;
    string pattern;

    public RegexConstraint(string pattern, RegexOptions options = RegexOptions.CultureInvariant | RegexOptions.Compiled | RegexOptions.IgnoreCase)
    {
        regex = new Regex(pattern, options);
        this.pattern = pattern;
    }

    public bool Match(System.Web.HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        object val;
        values.TryGetValue(parameterName, out val);
        string input = Convert.ToString(val, CultureInfo.InvariantCulture);
        return regex.IsMatch(input);
    }

    public string Pattern
    {
        get
        {
            return pattern;
        }
    }

    public RegexOptions RegexOptions
    {
        get
        {
            return regex.Options;
        }
    }

    private string Key
    {
        get
        {
            return regex.Options.ToString() + " | " + pattern;
        }
    }

    public override int GetHashCode()
    {
        return Key.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        var other = obj as RegexConstraint;
        if (other == null) return false;
        return Key == other.Key;
    }

    public bool Equals(RegexConstraint other)
    {
        return this.Equals((object)other);
    }

    public override string ToString()
    {
        return "RegexConstraint (" + Pattern + ")";
    }
}


文章来源: First call to Url.Action on a page is slow