Thứ Hai, 26 tháng 11, 2012

Tăng tốc cho ứng dụng ASP.NET MVC với Output Caching

Trong bài hướng dẫn này, bạn sẽ học cách tăng tốc độ ứng dụng ASP.NET MVC bằng cách sử dụng output caching. Bạn sẽ học cách cache kết quả trả về từ controller action do đó nội dung đó sẽ không cần phải tạo lại mỗi khi người dùng gọi đến action đó.

 

Trong bài hướng dẫn này, bạn sẽ học cách tăng tốc độ ứng dụng ASP.NET MVC bằng cách sử dụng output caching. Bạn sẽ học cách cache kết quả trả về từ controller action do đó nội dung đó sẽ không cần phải tạo lại mỗi khi người dùng gọi đến action đó.

Ví dụ như ứng dụng ASP.NET MVC của bạn hiển thị danh sách các dòng dữ liệu lấy từ Database ra một View có tên là Index, mỗi khi người dùng gọi controller action trả về view Index, dữ liệu trên sẽ được trả về từ CSDL bằng cách gọi một câu truy vấn đến CSDL.

Nhưng nếu như bạn sử dụng ouput cache thì bạn sẽ tránh được việc phải thực hiện câu truy vấn CSDL mỗi khi action đó được gọi. View sẽ được lấy lên từ cache (bộ nhớ tạm của ứng dụng) thay vì phải gọi action tạo ra dữ liệu và trả kết quả về. Caching giúp cho bạn tránh phải bắt server thực thi lặp đi lặp lại một hành động.

Hữu hiệu Output Caching

Bạn có thể cho phép output caching bằng cách thêm thuộc tính [OutputCache] cho controller action hoặc cho cả controller. Ở Mã minh họa 1, action có tên là Index sẽ được cache trong mỗi mười giây.

 

Mã minh họa 1 – Controllers\HomeController.cs

 


using System.Web.Mvc;    namespace MvcApplication1.Controllers  {      [HandleError]      public class HomeController : Controller      {          [OutputCache(Duration=10, VaryByParam="none")]          public ActionResult Index()          {              return View();          }        }  }     

 

 

Trong mã minh họa 1, nội dung trả về của action Index() được cache trong 10 giây. Nếu bạn thích, bạn có thể quy định thời gian cache (cache duration) dài hơn. Ví dụ, nếu bạn muốn cache một action trong một ngày, bạn có thể quy định thời lượng cach trong 86400 giây ( 60 giây * 60 phút * 24 giờ).

Tuy nhiên, không có gì đảm bảo nội dung sẽ được cache trong thời lượng bạn quy định. Khi tài nguyên bộ nhớ thấp, nội dung cache sẽ bị xóa tự động.

Controller Home trong mã minh họa 1 trả về view Index trong mã minh họa 2. View này chả có nội dung gì đặc biệt, nó chỉ hiển thị thời gian hiện tại (xem Hình 1).

Mã minh họa 2 – Views\Home\Index.aspx

 


<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="MvcApplication1.Views.Home.Index" %>  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  <html xmlns="http://www.w3.org/1999/xhtml" >  <head runat="server">      <title>Index</title>  </head>  <body>      <div>            The current time is: <%= DateTime.Now.ToString("T") %>                  </div>  </body>  </html>     

 

 

Hình 1 – view Index đã bị cache

Nếu như bạn gọi action Index() nhiều lần thì bạn sẽ thấy thời gian hiển trị trên view Index sẽ không thay đổi trong vòng 10 giây bởi vì kết quả này đã bị cache.

Bạn cũng phải lưu ý rằng, view này sẽ bị cache và kết quả sẽ được lấy từ cache để cung cấp cho bất cứ ai thăm ứng dụng của bạn. Điều này có nghĩa rằng, thời gian mà web server phải sử dụng để phục vụ view Index cho người dùng được giảm đi đáng kể.

Đừng dụng chỉ thị <%@ OuputCache %> trong view. Chỉ thị này dành riêng cho ứng dụng Web Forms và không nên được dùng trong ứng dụng ASP.NET MVC.

Các nội dung được cache ở đâu?

Theo mặc định, khi bạn sử dụng thuộc tính [OutputCache], nội dung được cache ở ba nơi: ở web server, bất kỳ proxy server nào và web browser. Bạn có thể quy định nơi nào được cache bằng cách thay đổi thuộc tính Location của [OuputCache].

Bạn có thể quy định các giá trị sau cho thuộc tính Location:

· Any

· Client

· Downstream

· Server

· None

· ServerAndClient

Giá trị mặc định của thuộc tính Location có giá trị là Any. Tuy nhiên, có những tình huống mà bạn chỉ muốn cache ở trình duyệt hoặc ở server mà thôi. Ví dụ, nếu bạn muốn cache thông tin được tùy biến cho người dùng, do đó bạn không nên cache thông tin ở server.

Ví dụ, controller ở mã minh họa 3 có một action GetName() trả về tên người dùng hiện tại. Giả sử có người tên "Minh" là người đầu tiên triệu gọi action này, thì những người dùng sau khi triệu gọi trong vòng 1 phút sẽ được trả về kết quả là "Hi Minh" vì nội dung đã được cache ở server.

Mã minh họa 3 – Controllers\BadUserController.cs

 


using System.Web.Mvc;  using System.Web.UI;    namespace MvcApplication1.Controllers  {      public class BadUserController : Controller      {          [OutputCache(Duration = 3600, VaryByParam = "none")]          public string GetName()          {              return "Hi " + User.Identity.Name;          }      }  }     

 

 

Bạn không nên cache nội dung mang tính cá nhân ở server. Thay vào đó, bạn nên cache chúng ở cache của trình duyệt để tăng tốc độ cho ứng dung. Nếu bạn cache nội dung ở trình duyệt và khi người dùng triệu gọi một action nhiều lần thì nội dung sẽ được trả về từ cache của trình duyệt thay vì được lấy từ server.

Ở mã minh họa 4, action GetName() đã được điều chỉnh để chỉ cache ở trình duyệt, và nhờ vậy, những người dùng khác nhau sẽ nhận được kết quả trả về là chính tên của họ chứ không phải tên của một người nào khác.

Mã minh họa 4 – Controllers\UserController.cs

 


using System.Web.Mvc;  using System.Web.UI;    namespace MvcApplication1.Controllers  {      public class UserController : Controller      {          [OutputCache(Duration=3600, VaryByParam="none", Location=OutputCacheLocation.Client, NoStore=true)]          public string GetName()          {              return "Hi " + User.Identity.Name;          }      }  }     

 

 

Lưu ý rằng thuộc tính [OuputCache] ở Mã minh họa 4 có bao gồm thuộc tính NoStore. Thuộc tính NoStore với giá trị true có tác dụng yêu cầu proxy servers và trình duyệt không lưu bản sao của nội dung được cache.

Cache action theo tham số

Trong một số trường hợp, bạn sẽ muốn có các phiên bản cache khác nhau cho cùng một nội dung. Ví như khi bạn tạo một trang dạng master/detail. Trang master hiển thị danh sách các tiêu đề phim, khi bạn click chuột vào tên một phim thì bạn sẽ nhận được nội dung giới thiệu chi tiết về phim đó.

Nếu bạn cache nội dung trang chi tiết, thì chi tiết của phim được hiển thị chung nội dung phim được cache bất kể bạn click vào tên phim nào. Và nội dung phim mà người dùng đầu tiên xem sẽ được cache cho những người xem sau.

Bạn có thể khắc phục lỗi này bằng cách sử dụng thuộc tính VaryByParam của [OutputCache]. Thuộc tính này giúp bạn tạo các phiên bản cache riêng biệt tùy theo giá trị của tham số và người dùng truy vấn một action.

Ví dụ, controller ở Mã minh họa 5 có hai action có tên là Master() và Details(). Action Master() trả về danh sách tên các phim và Details() trả về nội dung chi tiết của mỗi phim.

Mã minh họa 5 – Controllers\MoviesController.cs

 


using System.Linq;  using System.Web.Mvc;  using MvcApplication1.Models;    namespace MvcApplication1.Controllers  {      public class MoviesController : Controller      {          private MovieDataContext _dataContext;            public MoviesController()          {              _dataContext = new MovieDataContext();          }            [OutputCache(Duration=int.MaxValue, VaryByParam="none")]          public ActionResult Master()          {              ViewData.Model = (from m in _dataContext.Movies                                 select m).ToList();              return View();          }            [OutputCache(Duration = int.MaxValue, VaryByParam = "id")]          public ActionResult Details(int id)          {              ViewData.Model = _dataContext.Movies.SingleOrDefault(m => m.Id == id);              return View();          }          }  }     

 

 

Action Master() có đính kèm thuộc tính VaryByParam với giá trị là "none". Khi Master() được gọi, nội dung được cache duy nhất của view Master() sẽ được trả về (xem hình 2).

Hình 2 – /Movies/Master 

Hình 3 – /Movies/Details

Action Details() đính kèm thuộc tính VaryByParam với giá trị là "Id".  Và do đó, khi giá trị của tham số Id được truyền vào action thì sẽ có một phiên bản cache được sinh ra và lưu lại.

Ngoài ra bạn có thể gán các giá trị sau cho thuộc tính VaryByParam:

* = Tạo ra các phiên bản cache khác nhau đối với tham số truyền lên khác nhau

none = Chỉ duy trì phiên bản cache chung cho mọi giá trị tham số

Danh sách các tham số (phân tách bằng dấu ;) = Tạo các phiên bản cache khác nhau tùy theo giá trị của các tham số mà bạn quy định.

Tạo Cache Profile

Nhược điểm của việc quy định các tham số trực tiếp trên thuộc tính [OuputCache] đó là bạn không thể thay đổi nó khi đã biên dịch thành tập tin dll. Và vì vậy Microsoft cho phép quy định các tham số của thuộc tính [OuputCache] tại tận tin cấu hình web.config. Cách này mang lại cho hai lợi ích chính, thứ nhất là cho phép bạn áp dụng một cache profile cho nhiều action khác nhau. Lợi ích thứ hai, quan trọng không kém, cho phép bạn tùy chỉnh các tham số cấu hình mà không cần phải biên dịch lại dự án, mọi thay đối ở tập tin web.config sẽ được xác định tự động và có hiệu lực ngay sau đó.

Ví dụ, mục <caching> trong tập tin web.config ở Mã minh họa 6 định nghĩa một cache profile có tên là Cache1Hour. Mục <caching> được định nghĩa bên trong mục <system.web> của tập tin web.config.

Mã minh họa 6 – Caching section ở web.config

 


<caching>  <outputCacheSettings>      <outputCacheProfiles>          <add name="Cache1Hour" duration="3600" varyByParam="none"/>      </outputCacheProfiles>  </outputCacheSettings>  </caching>     

 

 

Controller trong Mã minh họa 7 minh họa cho bạn cách áp dụng cấu hình Cache1Hour cho action với thuộc tính [OuputCache].

Mã minh họa 7 – Controllers\ProfileController.cs

 


using System;  using System.Web.Mvc;    namespace MvcApplication1.Controllers  {      public class ProfileController : Controller      {          [OutputCache(CacheProfile="Cache1Hour")]          public string Index()          {              return DateTime.Now.ToString("T");          }      }  }     

 

 

Nếu bạn triệu gọi action Index() cho Mã minh họa 7 thì action sẽ được cache trong 1 giờ.

Tổng kết

Ouput caching giúp cho bạn có thể dễ dàng tăng tốc các ứng dụng ASP.NET MVC. Ở bài viết này, bạn được học cách sử dụng thuộc tính [OuputCache] để cache kết quả trả về bởi các action. Bạn cũng đã được học cách điều chỉnh các tham số của thuộc tính [OutputCache] như là Duration và VaryByParam để điều chỉnh cách thức cache nội dung trả về. Và cuối cùng bạn học được cách quy đính cấu hình cache trong tập tin web.config của ứng dụng.


Cảm ơn tác giả :  tumivn - Link nguồn : d.jou.vn/Article/Tang-toc-cho-ung-dung-ASPNET-MVC-voi-Output-Caching/13

Không có nhận xét nào:

Liên kết quảng cáo :