首次调用页面上的Url.Action很慢

Kei*_*ith 6 asp.net-mvc performance urlhelper route-constraint

我有一个相当简单的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页面),但即便如此,时间似乎太慢了.

任何想法如何解决它?

Kei*_*ith 5

发现问题,它与路由表(欢呼Kirill)有关.

基本上我们有很多看起来像这样的路线:

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) + ")" });
Run Code Online (Sandbox Code Playgroud)

事实证明,正则表达式检查非常缓慢,非常缓慢.所以我用一个实现替换它IRouteConstraint只是检查HashSet反而.

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

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

我还使用了链接文章中提到RegexConstraint来处理更复杂的事情 - 包括很多这样的调用(因为我们有遗留的WebForm页面):

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

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