Now a day, visiting a website on a desktop or on mobile is a daily job. But when we visit a website or a web application then we aspect that it will render very soon within 5 to 10 seconds. But unfortunately, very minimum websites are available those take minimum time to open [ex. Stackoverflow.com] and the reason behind are as following.
- Huge contents
- Large and multiple images
- Complex business logic
- Too much server request
- Poor connection
- Data access layer etc.
We can see here that several reasons behind the slowness of the website. So, what can we do here? To get resolve these issues which creates performance issue with the website, we can use Caching. Yes, using caching we can cache the data and if the user makes another request for the same type of data then we don’t need to go and get the same data again from sever or don’t need to perform same logic again and again.
Caching is a technique which helps us to store our data somewhere which we have already got and if we require the same data again then we can get it from stored data. Data can be saved at client side as well as server side. It totally depends on your requirements, not your choice.
Advantage of caching
If we define advantage of caching in one line, then it is “Performance” and it can be achieved to minimize following things.
- Minimize server round trips [Hosting Server or Database Server or Any Other Server]
- Minimize Network Traffic [Http Call to Server]
- Avoid repeating same data binding logic?
Tips and Tricks when using Asp.Net MVC caching
- Don’t use caching with the data which changes frequently.
- Don’t use caching with Authentication logic
- Don’t use caching with the data which is unique for the individual user
- Don’t use caching with data which use very rare like privacy policy page
- Don’t use caching for an Error page
- Use caching with data which is used very frequently and same data can be used by all user
- Always use caching with images or media files.
Generally, we can cache our data using 3 ways in Asp.Net MVC.
- Caching Static Contents,
- Caching whole or partial page response using OutputCache Attribute
- Caching shared data
Caching Static Contents
While designing any website, we have to use static contents. Static Content means which does not change dynamically like your images, CSS, javascript file etc. These are really heavy files and loading these from the server is a time-consuming task. Do you think how much time is taken to load these static contents? It probably more than 60% time are consuming by these types of contents to load. But that is perfect, if we use more static content then it will definitely take time to load.
But the question comes here that "Should it takes time to download these contents every time when we use the same page on the same browser again and again.The answer is NO. The downloading process should be the part of the first time, not everytime. So, what we can do here to achieve this. We can use Static Content Caching in Asp.Net MVC here to cache our downloaded static contents in memory and when we access the same page again then rather than going to download whole static contents again from the server. We just get these from the memory caches.
Let's understand it from a demonstration that how we can achieve static contents caching in Asp.Net MVC.
Here I have created on Asp.Net MVC 4 application. If you don't know how to create Asp.Net MVC application, just follow my previous articles. After creating an Asp.Net MVC application, go to Index view for the HomeController which is auto-generated and following codes. Here you can see, I have just added three images. For this demonstration, I have downloaded these images from google, you can test it with any images. So, when we run the application, these images will be downloaded from the server every time.
@{
ViewBag.Title = "Home Page";
}
<style>
table td {
padding: 10px;
border: 2px solid #808080;
text-align: center;
}
</style>
<div class="jumbotron">
<h3>Static Content Caching in Asp.Net MVC</h3>
<table>
<tr>
<td><img src="~/Content/img/image1.png" width="300" height="300" />Image 1</td>
<td><img src="~/Content/img/image2.jpg" width="300" height="300" />Image 2</td>
<td><img src="~/Content/img/image3.png" width="300" height="300" />Image 3</td>
</tr>
</table>
</div>
Here is Index Action method which is responsible for rendering our Index view.
//Static content caching
public ActionResult Index()
{
return View();
}
Now its time to run the application and see what happens. When we run the application and go to developer tools > Networks section then finds that each static contents like images, CSS or javascript files are being downloaded. But we refresh the same page again the same process repeat again and same files are being downloaded again and this is not a good choice.
To cache static contents, we have to define few configurations in our application's Web.Config file as below. Here you can see, we have defined the file extension with mime type which needs to be cache. To defining an age of caching time, we use "cacheControlMaxAge" attribute from "clientCache" and define the time here. For this demonstration, we have used 1 minutes.
<system.webServer>
<staticContent>
<clear/>
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="00:01:00" />
<mimeMap fileExtension=".jpg" mimeType="image/jpg"/>
<mimeMap fileExtension=".png" mimeType="image/jpg"/>
<mimeMap fileExtension=".css" mimeType="text/css"/>
<mimeMap fileExtension=".js" mimeType="text/javascript"/>
</staticContent>
<validation validateIntegratedModeConfiguration="false" />
<modules>
<remove name="ApplicationInsightsWebTracking" />
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" />
</modules>
</system.webServer>
So, now again time to run the application after configuration of caching for static contents. When we run the application first time, we see the same screen as above where we will find that each component is being downloaded in specific time. But if we run the application again within 1 minutes we will see the output as follows.
Following images show that each static component is getting from memory cache rather than download it from the server. So, here we have achieved static caching technique using this we can cache static contents and don't need to download these every time.
Output Caching
In Asp.Net MVC, we can cache page response using "OutputCache" attribute. This type of caching is basically used to cache your content generated by an action method. "OutputCache" attribute can be used with action level or controller level. In Output Caching, we can define the age of caching using Duration in seconds. Here we can also define the location for caching, it can be client side or server side or any. If we would like to cache contents using some parameter then it can be defined using "VaryByParam".
So, let understand it with an example. Now we will create a new action method as "Index1" as follows. Here we are creating a list for the blog post which contains 1000 records.
//Output caching
[OutputCache(Duration = 60, VaryByParam = "none", Location = System.Web.UI.OutputCacheLocation.Server)]
public ActionResult Index1()
{
var postModel = new List < BlogPost > ();
//Suppose getting blog post data form API call.
for (int i = 0; i < 1000; i++) {
postModel.Add(new BlogPost() {
PostId = i, Title = "Blog Post Title " + i, Category = "Category " + i, Content = "Content for Blog Post " + i
});
}
foreach(var item in postModel)
{
if (item.PostId % 2 == 0) {
item.UserName = "Mukesh Kumar";
} else {
item.UserName = "Admin";
}
}
return View(postModel);
}
Following is the entity class "BlogPost" for Blog.
namespace CachingInMVC.Models
{
public class BlogPost
{
public int PostId { get; set; }
public string Title { get; set; }
public string Category { get; set; }
public string Content { get; set; }
public string UserName { get; set; }
}
}
Now needs to create new view "Index1" inside the Home folder of the view as follows. This view basically renders all the blog post in tabular view. We have defined date time to see when our data last updated.
@model IEnumerable<CachingInMVC.Models.BlogPost>
@{
ViewBag.Title = "Home Page";
}
<style>
table td {
padding: 10px;
border: 2px solid #808080;
text-align: center;
}
</style>
<div class="jumbotron">
<h2>Output Caching in Asp.Net MVC</h2>
<h3>Last Update Data: <strong style="color:red;">@DateTime.Now.ToString()</strong></h3>
<br />
<table style="border:3px solid #808080;">
<tr>
<th>ID</th>
<th>Title</th>
<th>Category</th>
<th>Content</th>
<th>User</th>
</tr>
@foreach (var post in Model)
{
<tr style="border:1px solid #808080">
<td>@post.PostId</td>
<td>@post.Title</td>
<td>@post.Category</td>
<td>@post.Content</td>
<td>@post.UserName</td>
</tr>
}
</table>
</div>
When we run the application, we will find the output as below where we can see time for last updated data along with blog post data in tabular format. As above with action method, we are using Output Caching with duration 60 seconds. So, if reload this page again within 60 seconds then it will not process whole code for "Index1" and render data from the cache.
Here we have reloaded the page again then page rendered very quickly and see the data same as the previous result along with time for last updated data is same. Because everything is getting from the server rather than executing the whole code again for "Index1".
Common Data Caching
Now if we required sharing common data with multiple action method and would like to add this type of data in the cache then we can use "HttpContext.Cache" for setting or getting the data. As we can see with below code, we are just using the same code which we have already used with Output Cache example above but here we have removed model data creating logic inside a method.
If first, we will try to check the data is available in Cache using the defined key, if data is there then we will render the data on view from the cache and if not then we will get the data from "getThousandsPost" method and bind the model. But make sure, before rendering the data is that we should add this data inside the cache so that next time we don't need to go and execute same logic again and again.
Getting the data from the cache.
Setting the data in the cache
//Common data caching
public ActionResult Index2()
{
var postModel = HttpContext.Cache.Get("ThousandsPost") as List < BlogPost > ;
if (postModel == null) {
postModel = this.getThousandsPost();
HttpContext.Cache.Insert("ThousandsPost", postModel, null, DateTime.Now.AddMinutes(1), Cache.NoSlidingExpiration);
}
return View(postModel);
}
private List < BlogPost > getThousandsPost()
{
List < BlogPost > post = new List < BlogPost > ();
//Suppose getting blog post data form API call.
for (int i = 0; i < 1000; i++)
{
post.Add(new BlogPost() {
PostId = i, Title = "Blog Post Title " + i, Category = "Category " + i, Content = "Content for Blog Post " + i
});
}
foreach(var item in post)
{
if (item.PostId % 2 == 0) {
item.UserName = "Mukesh Kumar";
} else {
item.UserName = "Admin";
}
}
return post;
}
Here using the new view "Index2" as follows.
@model IEnumerable<CachingInMVC.Models.BlogPost>
@{
ViewBag.Title = "Home Page";
}
<style>
table td {
padding: 10px;
border: 2px solid #808080;
text-align: center;
}
</style>
<div class="jumbotron">
<h2>Data Caching in Asp.Net MVC</h2>
<h3>Last Update Data: <strong style="color:red;">@DateTime.Now.ToString()</strong></h3>
<br />
<table style="border:3px solid #808080;">
<tr>
<th>ID</th>
<th>Title</th>
<th>Category</th>
<th>Content</th>
<th>User</th>
</tr>
@foreach (var post in Model)
{
<tr style="border:1px solid #808080">
<td>@post.PostId</td>
<td>@post.Title</td>
<td>@post.Category</td>
<td>@post.Content</td>
<td>@post.UserName</td>
</tr>
}
</table>
</div>
When we run the application, we will notice one that our date time is being changed every time. It is because date time is not a part of the cache. We have defined it in the view. To check, data is loading from cache or not, just put a breakpoint in the "getThousandsPost()" method and we will find the first time we will hit this method and once data is cached. We will get data from cache next time.
Conclusion
So, today we learned how to cache our data in Asp.Net MVC. Data can be any type, it could be static content or page response or common data which needs to be shared.
I hope this post will help you. Please put your feedback using comment which helps me to improve myself for next post. If you have any doubts please ask your doubts or query in the comment section and If you like this post, please share it with your friends. Thanks
Posted Comments :
MUKESH KUMAR humps goars Posted : 6 Years Ago
rofl this posting sucks the big homo dick MUKESH KUMAR exactly which muslim goat were u humping with your unit incher when u posted this crap
lokesh Posted : 5 Years Ago
post a article on routing concept in dependency injection
SNEHANJALI Posted : 3 Years Ago
Nice presentation, Thanks a lot
Diwas Poudel Posted : 6 Years Ago
Nice One:)