8

Tôi có một ứng dụng mà tôi vừa nâng cấp từ ASP.NET MVC1 lên ASP.NET MVC4 rc1.Hiệu suất nút cổ chai Url.Action - tôi có thể giải quyết vấn đề này không?

Nó sử dụng chế độ xem biểu mẫu web.

Nó có vấn đề hiệu suất bất cứ khi nào Url.Action (hành động, bộ điều khiển) được sử dụng.

Tôi có thể tạo lại sự cố trong ASP.NET MVC3.

Tôi cần 3ms để hiển thị chế độ xem có 10 phiên bản của trình trợ giúp Url.Action trong ASP.NET MVC1 và 40ms để hiển thị tương tự trong ASP.NET MVC3.

Tôi đã tìm thấy một số cách để làm cho nó render nhanh hơn:

  • Tôi di chuyển các tuyến đường mặc định để đầu

  • Tôi đã gỡ bỏ Url.Action và sử dụng các liên kết tĩnh

Điều này không cảm thấy đúng: ứng dụng là khá lớn và tôi cần sự tốt đẹp của một định tuyến làm việc phong nha trong đó. Tôi cũng không tự tin rằng tôi đã tìm thấy tất cả các tắc nghẽn hiệu suất. Định tuyến là một phần trung tâm của MVC: nếu có điều gì đó hoạt động kém, nó sẽ xuất hiện trong các phần khác nhau của ứng dụng.

Tôi có ấn tượng rằng MVC3 đã giới thiệu một số tính năng định tuyến (như ràng buộc regex) mà ngay cả khi tôi không sử dụng chúng dẫn đến một ứng dụng hoạt động kém.

Có điều gì tôi có thể làm như chuyển các tính năng định tuyến hoặc sử dụng một nhóm trình trợ giúp URL khác không?

Mã này tái tạo vấn đề:

action Index

public ActionResult Index() 
     { 

      return View(); 
     } 

index.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> 

Route đăng ký này trông lạ: nhưng tôi chỉ muốn mô phỏng không tôi rất phức tạp định tuyến. Đây không phải là 600 tuyến đường SO!

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" }); 
} 

EDIT

Mẫu mã được biên dịch chống lại MVC2 bây giờ. Trong VS2010 MVC2 có thể được biên dịch dựa trên .NET 3.5 hoặc 4.0.

Hiệu suất với 3,5 là tốt và 4.0 là xấu.

Tôi đoán điều này có nghĩa là phần hoạt động kém không nằm trong hội đồng MVC nhưng trong một khung công tác khung (như System.Web.Routing.dll). Câu hỏi vẫn như cũ: Tôi có thể làm gì đó không? Một câu trả lời chấp nhận cũng sẽ là: Không, mã là chậm vì từ phiên bản 3,5-4,0 MS thay đổi XXX

EDIT-2

Tôi phân tích với một phần của System.Web.Routing.dll mất nhiều thời gian. Nó sử dụng một biểu thức chính quy được biên dịch. Có một đường dẫn mã (constraint2.Match) trả về mà không thực thi regex, nhưng tôi chưa kiểm tra nếu nó sử dụng nội bộ một hoạt động đắt tiền khác.

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); 
} 
+0

Điều này có xảy ra với yêu cầu đầu tiên hay mọi lúc không? – dknaack

+0

Yêu cầu đầu tiên là chậm hơn, thời gian tôi bị phạt là yêu cầu thứ hai. Và đó là tất cả trong chế độ "phát hành". –

+0

Chỉ cần ra khỏi tò mò có bạn đã thử nó mà không có tất cả các hướng dẫn IgnoreRoute? – JTMon

Trả lời

3

Có vấn đề được giải quyết tương tự như của bạn: First call to Url.Action on a page is slow có kết luận về ràng buộc định tuyến với ràng buộc regexp rất chậm.

+0

Sử dụng thực hiện của riêng tôi của IRouteConstraint như mô tả trong câu trả lời được chấp nhận giải quyết được vấn đề. –

0

Mỗi chế độ xem được biên soạn và lưu vào bộ nhớ cache khi được sử dụng lần đầu tiên. Tuy nhiên, vì Aspx Views không được thiết kế đặc biệt cho Mvc mỗi Url.Action không được biên dịch một lần cho tất cả trong liên kết cuối cùng nhưng nó được tính toán lại tại mỗi lần thực thi. Trình biên dịch Razor có tối ưu hóa tốt hơn. Giải pháp duy nhất là tính toán các liên kết khác nhau với Url.Action và lưu trữ chúng vào một số thuộc tính cấp ứng dụng, do đó, nó được tính ngay lúc thực hiện đầu tiên. Bạn có thể đặt chúng trong Từ điển ứng dụng hoặc trong các thuộc tính tĩnh của một lớp.

0

Tôi không chắc chắn nguyên nhân của những gì bạn đang thấy, nhưng nó có thể không chỉ là MVC 1 so với MVC 4, thiết lập IIS trong các phiên bản sau có thể ảnh hưởng đến tốc độ hiển thị xem. Tôi đã đi qua một sàn trượt một vài tháng trước đây mà tôi nghĩ là khá thú vị, liên quan đến lời khuyên cải thiện hiệu suất trong các ứng dụng MVC 3.

http://www.slideshare.net/ardalis/improving-aspnet-mvc-application-performance

Cụ thể, hãy nhìn vào trượt 28, trong đó nêu:

Uninstall IIS UrlRewrite Mô-đun

  • Nếu không có ứng dụng trên máy chủ đang sử dụng nó
  • Không có hiệu lực trong ứng dụng MVC trước v3
  • .210
  • Nâng cao tốc độ của thế hệ URL

tôi thực hiện việc này để có nghĩa là các mô-đun UrlRewrite sẽ tác động tiêu cực đến MVC 3, nhưng không phải MVC 2 hoặc 1, mà có thể là một nguồn gốc của suy thoái mà bạn đang nhìn thấy. Có một số cải tiến khác nữa, nhưng tôi không tin rằng bất kỳ một trong số họ 'trực tiếp' có liên quan đến những gì bạn đang thấy.

Các vấn đề liên quan