Cache کردن اطلاعات ASP.NET MVC
بسم الله الرحمن الرحیم
در این بخش قصد داریم نحوه افزایش سرعت بارگذاری صفحات در ASP.NET MVC را بررسی کنیم.
افزایش سرعت صفحات در ASP.NET MVC
برای افزایش کارایی برنامه های تحت وب Cache کردن اطلاعات بسیار مهم است. کش کردن اطلاعات یک راه برای ذخیره سازی اطلاعاتی است که مجددا باید مورد دسترسی قرار می گیرند. در عمل این یک راه موثر برای افزایش کارایی وب سایت ها است.
مزایای کش کردن اطلاعات
کاهش میزبانی اطلاعات بر روی سرور
هنگامی که شما اطلاعات را بر روی کلاینت یا پروکسی کش می کنید، عملا سرور شما درخواست های کمتری را باید پاسخ دهد.
کاهش فشار بر روی پایگاه داده
وقتی شما اطلاعات را در وب سرور کش کنید، می توانید درخواست ها را از دیتابیس حذف کنید.
کاهش ترافیک شبکه
هنگامی که شما اطلاعات را بر روی کلاینت کش می کنید، ترافیک شبکه شما کاهش پیدا می کند.
حذف زمان ها برای بازیابی اطلاعات تکراری
زمان هایی که صرف استفاده از اطلاعاتی که چندین بار مورد درخواست قرار خواهند گرفت، حذف می شود
افزایش کارایی
هنگامی که اطلاعات را کش می کنید، زمان کمتری برای بازیابی اطلاعات لازم است، ترافیک شبکه کمتر مصرف می شود، به سرور کمتر برای پاسخگویی نیاز خواهد بود و همه این کارهای باعث می شود تا کارایی سایت شما افزایش پیدا کند.
نکاتی در مورد کش کردن اطلاعات
اطلاعاتی که به صورت متناوب و مکرر مورد دسترسی قرار می گیرند را کش کنید.
از اطلاعاتی که برای هر کاربر منحصر به فرد است در کش کردن خودداری کنید.
البته ما این کار را دقیقا در ASP.NET Identity و در بحث Claims انجلم می دهیم زیرا اطلاعاتی که کش می شوند متناوب مورد نیاز هستند می خواهیم سرعت وب سایت را افزایش دهیم. این جمله کلی است و باید شما وابسته به استفاده خود از این جمله تبعیت یا عدم تبعیت کنید.
استفاده از تابع VaryByCustom برای کش کردن نسخه های متفاوت از یک صفحه بر اساس درخواست های سفارشی چون cookies, role, theme, browser
برای کش کردن با کارایی بالا از نسخه 64-bit ویندوز سرور و SQL Server استفاده کنید.
برای کش کردن اطلاعات دیتابیس مطمئن شوید به اندازه کافی Ram در اختیار دارید در غیر این صورت با کش کردن به دلیل استفاده از Ram زیاد نه تنها کارایی را افزایش نمی دهید، بلکه سرعت کار نیز کاهش پیدا می کند.
برای اطلاعاتی که مداوم در حال تغییر هستند یک زمان برای از بین رفتن کش در نظر بگیرید.
Output Cache Filter
Output Cache Filter به شما اجازه می دهد تا اطلاعاتی که درون یک متد action به عنوان خروجی نمایش داده خواهند شده را کش کنید. به صورت پیش فرض این خاصیت بعد از مدت 60 ثانیه از بین خواهد رفت. بعد از 60 ثانیه ASP.NET MVC این اطلاعات جدید را دوباره کش می کند.
Enabling Output Caching
شما می توانید Output Caching برای یک action و یا یک controller به صورت زیر فعال کنید:
[OutputCache(Duration=20, VaryByParam="none")]
public ActionResult Index()
{
ViewBag.Message = DateTime.Now.ToString();
return View();
}
خروجی Index() action برای مدت 20 ثانیه کش می شود در صورتی که شما این مقدار را تعیین نکنید به صورت پیش فرض زمان بر روی 60 ثانیه تنظیم شده است.
برای اینکه بتوانید فرایند دوباره کش شدن اطلاعات را مشاهده کنید کافی است بر روی کدها break point قرار دهید تا این فرایند مانند تصویر زیر مشاهده کنید:
OutputCache Filter Parameter
پارامتر |
نوع | توضیحات |
CacheProfile |
String |
نام output cache policy به وسیله تعریف کردن تگ <outputCacheSettings> در فایل Web.config مشخص می کند. |
Duration |
Int |
مدت زمان cache شدن اطلاعات را مخشص می کند. |
Location |
OutputCacheLocation |
مکان cache اطلاعات را مشخص می کند که به صورت پیش فرض Any است. |
NoStore |
Bool |
برای مشخص کردن مواردی که شما می خواهید HTTP Cache-Control را فعال و غیر فعال کنید. این فقط برای حفاظت از اطلاعات حساس است. |
SqlDependency |
String |
برای مشخص کردن دیتابیس و جدوالی است که می خواهید Cache کنید، خیلی جالب است با تغییر اطلاعات در دیتابیس این اطلاعات Cache شده نیز بروز می شوند. |
VaryByContentEncoding |
String |
سمیکولن را به عنوان کارکتر جدا کننده در لیست ها مشخص می کند (مانند Gzip) که خروجی Cache از روش متفاوتی برای Cache کردن استفاده می کند. |
VaryByCustom |
String |
برای مشخص کردن custom strings است که خروجی Cache از روش متفاوتی برای Cache کردن استفاده می کند. |
VaryByHeader |
String |
لیست های تفکیک شده با سمیکولن از نام های HTTP header که از روش متفاوتی برای Cache کردن استفاده می کند. |
VaryByParam |
String |
لیست های تفکیک شده با سمیکولن از فرمهایی که به صورت POST یا query string ارسال می شوند و از روش متفاوتی برای Cache کردن استفاده می کند. به صورت پیش فرض Cache نمی شوند و مقدار آن none است. |
آموزش SqlDependency را در چندین مطلب بررسی آموزش داده ایم برای آشنایی با این بخش به این مقاله مراجعه کنید.
Output Caching Location
به صورت پیش فرض اطلاعات در سه بخش کش می شود
- web server
- any proxy servers
- user's browser
شما می توانید بخش هایی که می خواهید اطلاعات بر روی آنها کش شود را کنترل کنید. برای تغییر مکان های کش شدن اطلاعات کافی است مقدار پارامتر location را در OutputCache تنظیم کنید. این پارامتر می توانید اطلاعات زیر را دریافت کند:
- Any
- None
- Client
- Server
- ServerAndClient
- Downstream
به صورت پیش فرض پارامتر location دارای مقدار Any است که برای بسیاری از سناریو ها مناسب است اما در بعضی مواقع شما نیاز دارید برای کار خود این فرایند کش شدن اطلاعات را عوض کنید.
مثال ساده برای این مطلب می تواند فرم لاگین باشد. وقتی شما اطلاعات یک کاربر را دریافت می کنید اطلاعات او را در مرورگر کش می کنید تا همیشه بدایند او کیست، حال اکر این اطلاعات را در سرور کش کنید اطلاعات تمامی کاربرها مربوط به اخرین فردی است که لاگین کرده.
این نکته را همیشه به یاد داشته باشید، هر وقت اطلاعاتی برای تمامی کاربران یکسان و مورد نیاز است آن را بر روی سرور کش کنید.
Configure Cache Location
برای تنظیم مکان کش شدن اطلاعات باید ابتدا namespace یا همان فضای نامی System.Web.UI را به Controller خود اضافه کنید و سپس به صورت زیر می توانید مکان کش شدن اطلاعات را در Browser کاربر مشخص کنید.
[OutputCache(Duration = 7200, Location = OutputCacheLocation.Client, VaryByParam = "none", NoStore = true)]
public ActionResult Index()
{
ViewBag.Message = "Welcome : " + User.Identity.Name;
return View();
}
نظرات (۴)
با عرض سلام
اگر موضوع خاصی را مد نظر دارید اطلاع دهید تا در مورد آن مطلبی ارائه شود و دوستان دیگر نیز از آن استفاده کنند.
باتشکر
با عرض سلام خدمت شما
می توانید با تعریف یک filter جدید که قابلیت های کش را پیاده سازی می کند، کمی در مدیریت کش دخل و تصرف داشته باشید:
public class ActionOutputCacheAttribute : ActionFilterAttribute { // This hack is optional; I'll explain it later in the blog post private static MethodInfo _switchWriterMethod = typeof(HttpResponse).GetMethod("SwitchWriter", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); public ActionOutputCacheAttribute(int cacheDuration) { _cacheDuration = cacheDuration; } private int _cacheDuration; private TextWriter _originalWriter; private string _cacheKey; public override void OnActionExecuting(ActionExecutingContext filterContext) { _cacheKey = ComputeCacheKey(filterContext); string cachedOutput = (string)filterContext.HttpContext.Cache[_cacheKey]; if (cachedOutput != null) filterContext.Result = new ContentResult { Content = cachedOutput }; else _originalWriter = (TextWriter)_switchWriterMethod.Invoke(HttpContext.Current.Response, new object[] { new HtmlTextWriter(new StringWriter()) }); } public override void OnResultExecuted(ResultExecutedContext filterContext) { if (_originalWriter != null) // Must complete the caching { HtmlTextWriter cacheWriter = (HtmlTextWriter)_switchWriterMethod.Invoke(HttpContext.Current.Response, new object[] { _originalWriter }); string textWritten = ((StringWriter)cacheWriter.InnerWriter).ToString(); filterContext.HttpContext.Response.Write(textWritten); filterContext.HttpContext.Cache.Add(_cacheKey, textWritten, null, DateTime.Now.AddSeconds(_cacheDuration), Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, null); } } private string ComputeCacheKey(ActionExecutingContext filterContext) { var keyBuilder = new StringBuilder(); foreach (var pair in filterContext.RouteData.Values) keyBuilder.AppendFormat("rd{0}_{1}_", pair.Key.GetHashCode(), pair.Value.GetHashCode()); foreach (var pair in filterContext.ActionParameters) keyBuilder.AppendFormat("ap{0}_{1}_", pair.Key.GetHashCode(), pair.Value.GetHashCode()); return keyBuilder.ToString(); } }
و در نهایت
public class BlogController : Controller { [ActionOutputCache(60)] // Caches for 60 seconds public ActionResult LatestPosts() { ViewData["currentTime"] = DateTime.Now; ViewData["posts"] = new[] { "Here's a post", "Here's another post. Marvellous.", "Programmer escapes from custody" }; return View(); } }
یاعلی
با عرض سلام
برای اینکار باید با استفاده از Ajax و java script، یک timer را طراحی کنید بنده راهکاری برای استفاده و تعیین مستقیم مدت زمان باقی مانده سراغ ندارم
موفق باشید
بابت تاخیر در پاسخ عذرخواهی می کنم، پاسخی نتوانستم برای درخوسات شما پیدا کنم.
موفق باشید
یاعلی
لطفا در مورد کوکی ها و همینطور ایجکس جی کوری هم مطلب بذارید