我有一个非常简单的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.Action
和Html.BeginForm
。 然而,想必是使用所有的地方? 我的意思是,½第二是过于缓慢。
我有20个左右的定制路由(这是一个相当大的应用程序有一些旧的WebForms页)但即使是这样的时代似乎过于缓慢。
任何想法如何解决呢?
发现问题,并且它与路由表(欢呼基里尔)。
基本上我们有很多途径,看起来是这样的:
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.Action
和Html.BeginForm
现在需要大量的时间可以忽略不计(甚至有很多路线)。
在我看来,你的问题正在编制的意见。 你需要向预编译生成的观点和这一问题将消失。 这里的细节
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 + ")";
}
}