asp.net-mvc-3 - 性能瓶颈 Url.Action - 我可以解决它吗?

标签 asp.net-mvc-3 asp.net-mvc-2 asp.net-mvc-routing asp.net-4.0 asp.net-3.5

我有一个应用程序,我最近从 ASP.NET MVC1 升级到了 ASP.NET MVC4 rc1。

它使用 Webforms View 引擎。

每当使用 Url.Action(action,controller) 时,它都会出现性能问题。

我可以在 ASP.NET MVC3 中重现这个问题。

我需要 3 毫秒来呈现在 ASP.NET MVC1 中包含 10 个 Url.Action 助手实例的 View ,而在 ASP.NET MVC3 中需要 40 毫秒来呈现相同的 View 。

我已经找到了一些使其渲染速度更快的方法:

  • 我将默认路由移到顶部
  • 我删除了 Url.Action 并使用了静态链接

  • 这感觉不对:应用程序非常大,我需要在其中使用体面的工作路由的优点。我也不相信我发现了所有的性能瓶颈。路由是 MVC 的核心部分:如果有一些表现不佳的东西,它会在应用程序的不同部分弹出。

    我的印象是 MVC3 引入了一些路由功能(如正则表达式约束),即使我不使用它们也会导致应用程序性能不佳。

    有什么我可以做的事情,比如改变路由功能或使用一组不同的 URL 助手?

    此代码重现了该问题:

    索引操作
    public ActionResult Index()
            {
    
                return View();
            }
    

    索引.aspx
    <%@ Page Language="C#"  Inherits="System.Web.Mvc.ViewPage" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head >
        <title></title>
        <link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
    </head>
    
    <body>
        <div class="page">
    <%= Url.Action("Action1", "Controller1") %>
    <%= Url.Action("Action2", "Controller2") %>
    <%= Url.Action("Action3", "Controller3") %>
    <%= Url.Action("Action4", "Controller4") %>
    <%= Url.Action("Action5", "Controller5") %>
    <%= Url.Action("Action6", "Controller6") %>
    <%= Url.Action("Action7", "Controller7") %>
    <%= Url.Action("Action8", "Controller8") %>
    <%= Url.Action("Action9", "Controller9") %>
    <%= Url.Action("Action10", "Controller10") %>
        </div>
    </body>
    </html>
    

    路线登记
    这看起来很奇怪:但我只想模拟我不太复杂的路由。这不是SO的600路由!
    public static void RegisterRoutesSlow(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.IgnoreRoute("{language}/Content/{*pathInfo}");
    
        routes.IgnoreRoute("images/{*pathinfo}");
        routes.IgnoreRoute("scripts/{*pathinfo}");
        routes.IgnoreRoute("content/{*pathinfo}");
        routes.IgnoreRoute("{file}.gif");
        routes.IgnoreRoute("{file}.jpg");
        routes.IgnoreRoute("{file}.js");
        routes.IgnoreRoute("{file}.css");
        routes.IgnoreRoute("{file}.png");
        routes.IgnoreRoute("{file}.pdf");
        routes.IgnoreRoute("{file}.htm");
        routes.IgnoreRoute("{file}.html");
        routes.IgnoreRoute("{file}.swf");
        routes.IgnoreRoute("{file}.txt");
        routes.IgnoreRoute("{file}.xml");
        routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });
    
        for (int i = 0; i <= 10; i++)
        {
            routes.MapRoute(
                // Route name
                "RouteName" + i.ToString(),
                // URL with parameters                              
                "{language}/{controller}/{action}/{para1}",
                // Parameter defaults
                new
                {
                    action = "Index",
                    language = "de",
                    para1 = 0
                },
                //Parameter constraints
                new { language = "de|en", controller = "SomeNameOfAnActualController" + i.ToString() }
                );
        }
        routes.MapRoute(
                       "DefaulRoute",            // Route name
                       "{controller}/{action}",    // URL with parameters
                       new
                       {
                           controller = "Home",
                           action = "Index",
                       }
                   );
        routes.MapRoute("404-PageNotFound", "{*url}", new { controller = "Error", action = "PageNotFound", language = "de" });
    }
    

    编辑

    示例代码现在是针对 MVC2 编译的。在 VS2010 中,MVC2 可以针对 .NET 3.5 或 4.0 进行编译。

    3.5 的性能好,4.0 的性能差。

    我想这意味着性能不佳的部分不在 MVC 程序集中,而是在框架程序集中(如 System.Web.Routing.dll)。问题还是一样:我可以做些什么吗?可接受的答案也是:不,代码很慢,因为从 3.5 版到 4.0 版 MS 更改了 XXX

    编辑 2

    我反编译了 System.Web.Routing.dll 需要很长时间的部分。它使用编译的正则表达式。有一个代码路径 (constraint2.Match ) 在不执行正则表达式的情况下返回,但我还没有检查它是否在内部使用了不同的昂贵操作。
    protected virtual bool ProcessConstraint(HttpContextBase httpContext, object constraint, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        object obj2;
        IRouteConstraint constraint2 = constraint as IRouteConstraint;
        if (constraint2 != null)
        {
            return constraint2.Match(httpContext, this, parameterName, values, routeDirection);
        }
        string str = constraint as string;
        if (str == null)
        {
            throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, SR.GetString("Route_ValidationMustBeStringOrCustomConstraint"), new object[] { parameterName, this.Url }));
        }
        values.TryGetValue(parameterName, out obj2);
        string input = Convert.ToString(obj2, CultureInfo.InvariantCulture);
        string pattern = "^(" + str + ")$";
        return Regex.IsMatch(input, pattern, RegexOptions.CultureInvariant | RegexOptions.Compiled | RegexOptions.IgnoreCase);
    }
    

    最佳答案

    已经解决了与您类似的问题:First call to Url.Action on a page is slow
    有关于非常慢的正则表达式约束的路由约束的结论。

    关于asp.net-mvc-3 - 性能瓶颈 Url.Action - 我可以解决它吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11892335/

    相关文章:

    c# - 带有 Razor 的 ASP.NET MVC 3 可重用表显示模板

    html - 如何在 ASP.NET MVC View 中使用@page CSS

    vb.net - 我可以在 vb .net 中使用关键字作为属性名吗?

    asp.net-mvc - 参数中带有斜杠的 URL?

    asp.net - 在处理请求之前找出 Controller 的名称和操作

    asp.net-mvc - 使用 url 值作为路由值中的变量

    asp.net-mvc - 在 Razor View 引擎和 ASP.NET MVC 3 中使用动态模型渲染部分 View

    c# - 没有访问服务器配置的 asp.net mvc 2 的 GZip 或 Deflate 压缩

    asp.net-mvc-2 - 我的 MVC2 站点需要 crossdomain.xml 文件吗?

    asp.net-mvc - 如何使用 MVC 从另一个屏幕移动到另一个屏幕?