第一次调用Url.Action在页面上的速度很慢 [英] First call to Url.Action on a page is slow

查看:103
本文介绍了第一次调用Url.Action在页面上的速度很慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用相当简单的ASP.MVC视图时遇到性能问题.

I have a performance issue with a fairly simple ASP.MVC view.

这是一个登录页面,应该几乎是即时的,但是大约需要半秒钟.

It's a log-on page that should be almost instant, but is taking about half a second.

经过大量挖掘,似乎是第一个调用Url.Action的问题-大约需要450毫秒(根据 MiniProfiler ),但似乎太慢了.

After a lot of digging it looks like the problem is the first call the Url.Action - it's taking around 450ms (according to MiniProfiler) but that seems insanely slow.

随后对Url.Action的调用花费的时间少于1ms,这与我的预期更加一致.

Subsequent calls to Url.Action are taking <1ms, which is more in line with what I would expect.

无论我使用Url.Action("action", "controller")还是Url.Action("action"),这都是一致的,但是如果使用Url.Content("~/controller/action"),这似乎不会发生.当我呼叫Html.BeginForm("action")时也会发生这种情况.

This is consistent whether I use Url.Action("action", "controller") or Url.Action("action"), but doesn't seem to happen if I use Url.Content("~/controller/action"). This also happens when I call Html.BeginForm("action").

有人知道这是什么原因吗?

Does anyone have any idea what's causing this?

深入研究提示RouteCollection.GetVirtualPath可能是罪魁祸首,因为这对于Url.ActionHtml.BeginForm都是常见的.但是,肯定在整个地方都使用过吗?我的意思是½秒太慢了.

A dig into the source suggests that RouteCollection.GetVirtualPath might be the culprit, as that's common to both Url.Action and Html.BeginForm. However, surely that's used all over the place? I mean, ½ a second is far too slow.

我有20条左右的自定义路由(这是一个带有一些旧版WebForms页面的相当大的应用程序),但即使那样,时间似乎也太慢了.

I have 20 or so custom routes (it's a fairly large app with some legacy WebForms pages) but even then the times seem far too slow.

有什么解决办法吗?

推荐答案

发现问题,并且与路由表有关(欢呼基里尔).

Problem found, and it is with the routing tables (cheers Kirill).

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

Basically we have lots of routes that look something like this:

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进行了检查.

It turns out that the Regex check is very slow, painfully slow. So I replaced it with an implementation of IRouteConstraint that just checks against a HashSet instead.

然后我更改了地图路线调用:

Then I changed the map route call:

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

我还将链接文章中提到的 RegexConstraint 用于更复杂的事情-包括许多这样的调用(因为我们有旧版WebForm页面):

I also used the RegexConstraint mentioned in that linked article for anything more complicated - including lots of calls like this (because we have legacy WebForm pages):

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

这两个简单的更改可以完全解决问题;现在Url.ActionHtml.BeginForm花费的时间可以忽略不计(即使有很多路线).

Those two simple changes completely fix the problem; Url.Action and Html.BeginForm now take a negligible amount of time (even with lots of routes).

这篇关于第一次调用Url.Action在页面上的速度很慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆