{"id":649,"date":"2015-08-07T16:38:00","date_gmt":"2015-08-07T16:38:00","guid":{"rendered":"https:\/\/staging.infragistics.com\/blogs\/?p=649"},"modified":"2025-02-20T07:24:43","modified_gmt":"2025-02-20T07:24:43","slug":"increase-performance-of-asp-net-app-2","status":"publish","type":"post","link":"https:\/\/www.infragistics.com\/blogs\/increase-performance-of-asp-net-app-2","title":{"rendered":"12 Tips To Increase the Performance of Your ASP.NET App \u2013 Part 1"},"content":{"rendered":"\n<p>Building and hosting a web application on a web server is insanely easy with ASP.NET and IIS. However, many opportunities and hidden configurations can be tweaked to make it a high-performance web application. In this series post, we will discuss some of the most unused or ignored tricks that can be easily applied to any web application.<\/p>\n\n\n\n<h2 class=\"wp-block-heading CxSpFirst\" class=\"wp-block-heading CxSpFirst\" id=\"1-kernel-mode-cache\">1. Kernel Mode Cache<\/h2>\n\n\n\n<p class=\"CxSpFirst\">It is one of the primary tools widely used for writing, making web applications faster. But most of the time, we don\u2019t use it optimally, leaving some major benefits.\u00a0 As each asp.net request goes through various stages, we can implement caching at multiple levels as below.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/community\/cfs-filesystemfile\/__key\/CommunityServer.Blogs.Components.WeblogFiles\/devtoolsguy.Maria_5F00_Blogs\/8206.Brij_5F00_post1.png\" alt=\" request response\" title=\" request response\"\/><\/figure>\n\n\n\n<p class=\"CxSpMiddle\">We can see that the request is first received by HTTP.sys, so if it is cached at the kernel level, then we can save most of the time spent on the server as HTTP.sys is an HTTP listener that sits in the OS kernel and listens to the request directly from TCP layer. We can save all the time spent on the IIS\/ASP.NET pipeline, page lifecycle, our custom code, the time taken in DB, etc. Let\u2019s see how we can implement it.<\/p>\n\n\n\n<p class=\"CxSpMiddle\">a)<span style=\"line-height: normal;\"><span style=\"font-family: Times New Roman;\"><span style=\"font-size: 7pt;\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span>Go to IIS and select the website.<\/p>\n\n\n\n<p class=\"CxSpMiddle\">b)<span style=\"line-height: normal;\"><span style=\"font-family: Times New Roman;\"><span style=\"font-size: 7pt;\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span>Click on Output Cache icon on right under IIS section<\/p>\n\n\n\n<p class=\"CxSpMiddle\">c)<span style=\"line-height: normal;\"><span style=\"font-family: Times New Roman;\"><span style=\"font-size: 7pt;\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span>In the right panel, under Actions click on Add. The following dialog will open:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/community\/cfs-filesystemfile\/__key\/CommunityServer.Blogs.Components.WeblogFiles\/devtoolsguy.Maria_5F00_Blogs\/5657.Brij_5F00_post2.png\" alt=\" \"\/><\/figure>\n\n\n\n<p class=\"CxSpMiddle\">Here, in the red encircled area, we must define the file extensions we want to cache at the kernel. For the second encircled area, we need to select the checkbox. The third encircled area shows that there are three options provided to invalidate the cache. Based on our requirements, we can configure it.<\/p>\n\n\n\n<p class=\"CxSpMiddle\">Note \u2013 there are some limitations to overcaching at the kernel level. As all the features of IIS are implemented at the user level, we will not be able to leverage any of them. <span style=\"box-sizing: border-box; margin: 0px; padding: 0px;\">Refer to this\u00a0<a href=\"https:\/\/support.microsoft.com\/en-us\/kb\/817445\" target=\"_blank\" rel=\"noopener\">MSDN<\/a>\u00a0article for a complete list of kernel caching that cannot be implemented.<\/span><\/p>\n\n\n\n<h2 class=\"wp-block-heading CxSpMiddle\" class=\"wp-block-heading CxSpMiddle\" id=\"2-pipeline-mode-available-on-iis-7\">2. Pipeline Mode (Available on IIS 7+)<\/h2>\n\n\n\n<p class=\"CxSpMiddle\">Two pipeline modes are available at the application pool level: classic and integrated. Classic is available to support the applications that were migrated from IIS6. So first, let\u2019s understand these modes. IIS provides many features that are implemented as modules in IIS, and in a similar way, many features are implemented as an HTTP Module, which is part of the ASP.NET Pipeline. In the classic mode, each request goes through the IIS pipeline and then the ASP.NET pipeline before getting served.<\/p>\n\n\n\n<p class=\"CxSpMiddle\">There are many features that are part of both pipelines, like Authentication, etc. In the case of\u00a0Integrated\u00a0mode, these two pipelines are merged into one, and all the modules (IIS and ASP.NET) are invoked from the single event as they come along, which reduces redundancy and is very helpful in the performance of an application.<\/p>\n\n\n\n<p class=\"CxSpMiddle\">To set\/update the pipeline mode, select the desired application pool and right-click the properties.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"316\" height=\"286\" src=\"https:\/\/staging.infragistics.com\/blogs\/wp-content\/uploads\/2015\/08\/4174.Brij_post3.png-1040x0-1.png\" alt=\"edit app pool\" class=\"wp-image-1226\" title=\"edit app pool\" srcset=\"https:\/\/www.infragistics.com\/blogs\/wp-content\/uploads\/2015\/08\/4174.Brij_post3.png-1040x0-1.png 316w, https:\/\/www.infragistics.com\/blogs\/wp-content\/uploads\/2015\/08\/4174.Brij_post3.png-1040x0-1-300x272.png 300w\" sizes=\"auto, (max-width: 316px) 100vw, 316px\" \/><\/figure>\n\n\n\n<p class=\"CxSpMiddle\">Here as encircled in the above pic, we can set the pipeline mode.<\/p>\n\n\n\n<p><em>Note \u2013 Don\u2019t go for blindly changing it, if your application migrated from IIS6 then there could be some dependency on it. After changing thoroughly test it before moving ahead.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"3-remove-unused-modules\">3. Remove Unused Modules<\/h2>\n\n\n\n<p>Each request has gone through the ASP.NET Pipeline, which contains many HTTP modules and, at the end, one HTTP handler, which serves the request as below.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/community\/cfs-filesystemfile\/__key\/CommunityServer.Blogs.Components.WeblogFiles\/devtoolsguy.Maria_5F00_Blogs\/5141.Brij_5F00_post4.png\" alt=\" \"\/><\/figure>\n\n\n\n<p>We can see here the request goes through each module, is processed by the handler, and then comes through again via the same modules. Let\u2019s see how many modules are, by default, enabled in an ASP.NET Application. I have added the below code to get all the modules.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">HttpApplication httpApps = HttpContext.ApplicationInstance;\n \n\/\/Get list of active modules\nHttpModuleCollection httpModuleCollections = httpApps.Modules;\nViewBag.ModulesCount = httpModuleCollections.Count;<\/pre>\n\n\n\n<p>This collection can be bound to any control, and it displays as:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/community\/cfs-filesystemfile\/__key\/CommunityServer.Blogs.Components.WeblogFiles\/devtoolsguy.Maria_5F00_Blogs\/8204.Brij_5F00_post5.png\" alt=\" \"\/><\/figure>\n\n\n\n<p>It shows eighteen modules, some of which we may not be using, but each request has to go through these modules. So we can remove these modules from the pipeline. To remove a module, we require adding\u00a0the configuration in web.config as:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"> &lt;system.webServer>\n    &lt;modules>\n      &lt;remove name=\"FormsAuthentication\" \/>\n      &lt;remove name=\"DefaultAuthentication\" \/>\n      &lt;remove name=\"OutputCache\" \/>\n      &lt;remove name=\"AnonymousIdentification\" \/>\n      &lt;remove name=\"RoleManager\" \/>\n    &lt;\/modules>\n  &lt;\/system.webServer><\/pre>\n\n\n\n<p>Here, we list down the modules that we want to remove with the remove tag. Now as we added here remove five modules, next time when we will check the active modules, it will be thirteen.<\/p>\n\n\n\n<p><em>Note \u2013 For this demo, I have used VS 2013, you may get a different number when using another version but the key point is that we should remove all the modules which are not required.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"4-runallmanagedmodulesforallrequests\">4. runAllManagedModulesForAllRequests<\/h2>\n\n\n\n<p>It is another configuration one must have seen in\u00a0<em>web.config<\/em>\u00a0or\u00a0<em>applicationHost.config<\/em>\u00a0where it is set globally for all the application on that IIS as:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;modules runAllManagedModulesForAllRequests=\"true\"><\/pre>\n\n\n\n<p><span style=\"box-sizing: border-box; margin: 0px; padding: 0px;\">It means all the modules would be running for all the requests coming to the application, but we normally don\u2019t require that because it should run only ASP.NET files, not other files like\u00a0<em>CSS, js, jpg, HTML,<\/em>\u00a0etc.<\/span> It means even the request of these resources going through the pipeline, which is unnecessary for these files, and it just adds extra overhead. But we cannot make it simply false at the application level. So there could be two ways &#8211;<\/p>\n\n\n\n<p class=\"CxSpFirst\">a)<span style=\"line-height: normal;\"><span style=\"font-family: Times New Roman;\"><span style=\"font-size: 7pt;\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span>Create a different application just for serving these static resources and set this setting as false in web.config.<\/p>\n\n\n\n<p class=\"CxSpMiddle\">b)<span style=\"line-height: normal;\"><span style=\"font-family: Times New Roman;\"><span style=\"font-size: 7pt;\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span>Or in the same application, put all the static resources in a folder and add a web.config file specific to that folder and make it <i>false<\/i>.<\/p>\n\n\n\n<p class=\"CxSpMiddle\">&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading CxSpLast\" class=\"wp-block-heading CxSpLast\" id=\"5-do-not-write-anything-in-the-folder-cinetpubwwwroot\">5. Do Not Write Anything in the Folder c:\\inetpub\\wwwroot<\/h2>\n\n\n\n<p class=\"CxSpLast\">A file watcher looks into the folder and restarts the corresponding application pool if there are any changes in this folder. This feature is available in IIS; if there is any change in web.config or any file, it restarts the application pool so that your modified application serves the request. Now say you write the application log in some text file inside the application folder which makes a couple of entries in each request, the application pool would be restarting that many times which would be hazardous for your application. So, don\u2019t write or change anything in this folder until it is not part of application binaries.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"6-remove-extra-view-engines\">6. Remove Extra View Engines<\/h2>\n\n\n\n<p><span style=\"box-sizing: border-box; margin: 0px; padding: 0px;\">a) As we know,\u00a0<em>View Engines<\/em>\u00a0is part of the MVC request life cycle and is responsible for finding the view and processing it. It allows us to add our own custom view engines as well. Let\u2019s create a default MVC application and try to return a view that<\/span> does not exist in the solution. Now, when we run this application, it shows the following error.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"614\" height=\"382\" src=\"https:\/\/staging.infragistics.com\/blogs\/wp-content\/uploads\/2015\/08\/4075.Brij_post6.png-1040x0-1.png\" alt=\"\" class=\"wp-image-1227\" srcset=\"https:\/\/www.infragistics.com\/blogs\/wp-content\/uploads\/2015\/08\/4075.Brij_post6.png-1040x0-1.png 614w, https:\/\/www.infragistics.com\/blogs\/wp-content\/uploads\/2015\/08\/4075.Brij_post6.png-1040x0-1-300x187.png 300w, https:\/\/www.infragistics.com\/blogs\/wp-content\/uploads\/2015\/08\/4075.Brij_post6.png-1040x0-1-480x299.png 480w\" sizes=\"auto, (max-width: 614px) 100vw, 614px\" \/><\/figure>\n\n\n\n<p>It shows that it is looking for the razor and aspx files to all the possible locations. But as we know, we are using the razor view engine, so it should not waste time looking at other aspx files because we already know that it will not be part of the solution. So we should remove all the extra View Engines.\u00a0\u00a0We need to add the following code in the\u00a0Application_Start\u00a0method, which is available in\u00a0Global.asax.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Removing all the view engines\nViewEngines.Engines.Clear();\n \n\/\/Add Razor Engine (which we are using)\nViewEngines.Engines.Add(new RazorViewEngine());<\/pre>\n\n\n\n<p>Now let\u2019s run it again<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"611\" height=\"293\" src=\"https:\/\/staging.infragistics.com\/blogs\/wp-content\/uploads\/2015\/08\/4075.Brij_post7.png-1040x0-1.png\" alt=\"\" class=\"wp-image-1228\" srcset=\"https:\/\/www.infragistics.com\/blogs\/wp-content\/uploads\/2015\/08\/4075.Brij_post7.png-1040x0-1.png 611w, https:\/\/www.infragistics.com\/blogs\/wp-content\/uploads\/2015\/08\/4075.Brij_post7.png-1040x0-1-300x144.png 300w, https:\/\/www.infragistics.com\/blogs\/wp-content\/uploads\/2015\/08\/4075.Brij_post7.png-1040x0-1-480x230.png 480w\" sizes=\"auto, (max-width: 611px) 100vw, 611px\" \/><\/figure>\n\n\n\n<p>Now, it is looking for only razor files<\/p>\n\n\n\n<p><span style=\"box-sizing: border-box; margin: 0px; padding: 0px;\">b)<span style=\"font-size:7pt\">\u00a0 \u00a0 \u00a0 <\/span>If we carefully see the above screens<\/span>hot, then we know that it is looking for c# and vb files and says in our solutions, we have never used vb, so again, there is no use in looking for\u00a0vbhtml\u00a0files. To fix this, we need to write our own custom <i>ViewEngine<\/i>. So let\u2019s write our Custom RazorViewEngine as:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">    public class MyCustomViewEngine : RazorViewEngine\n    {\n        public MyCustomViewEngine()\n        {\n            base.AreaViewLocationFormats = new string[] { \"~\/Areas\/{2}\/Views\/{1}\/{0}.cshtml\", \"~\/Areas\/{2}\/Views\/Shared\/{0}.cshtml\"};\n            base.AreaMasterLocationFormats = new string[] { \"~\/Areas\/{2}\/Views\/{1}\/{0}.cshtml\", \"~\/Areas\/{2}\/Views\/Shared\/{0}.cshtml\" };\n            base.AreaPartialViewLocationFormats = new string[] { \"~\/Areas\/{2}\/Views\/{1}\/{0}.cshtml\",\"~\/Areas\/{2}\/Views\/Shared\/{0}.cshtml\"};\n            base.ViewLocationFormats = new string[] { \"~\/Views\/{1}\/{0}.cshtml\", \"~\/Views\/Shared\/{0}.cshtml\" };\n            base.MasterLocationFormats = new string[] { \"~\/Views\/{1}\/{0}.cshtml\", \"~\/Views\/Shared\/{0}.cshtml\" };\n            base.PartialViewLocationFormats = new string[] { \"~\/Views\/{1}\/{0}.cshtml\", \"~\/Views\/Shared\/{0}.cshtml\" };\n            base.FileExtensions = new string[] { \"cshtml\" };\n        }\n    }<\/pre>\n\n\n\n<p><span style=\"box-sizing: border-box; margin: 0px; padding: 0px;\">Here, I have inherited it from\u00a0<em>RazorViewEngine,<\/em>\u00a0and if we see the constructor in the, then we find that there we have defined all the possible locations where a file can exist, which includes possible file extensions as well.<\/span> Now let\u2019s use this View Engine in\u00a0<em>Global.asax.<\/em><\/p>\n\n\n\n<p>And run the application.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"602\" height=\"240\" src=\"https:\/\/staging.infragistics.com\/blogs\/wp-content\/uploads\/2015\/08\/3010.Brij_post8.png-1040x0-1.png\" alt=\"\" class=\"wp-image-1229\" style=\"width:840px;height:auto\" srcset=\"https:\/\/www.infragistics.com\/blogs\/wp-content\/uploads\/2015\/08\/3010.Brij_post8.png-1040x0-1.png 602w, https:\/\/www.infragistics.com\/blogs\/wp-content\/uploads\/2015\/08\/3010.Brij_post8.png-1040x0-1-300x120.png 300w, https:\/\/www.infragistics.com\/blogs\/wp-content\/uploads\/2015\/08\/3010.Brij_post8.png-1040x0-1-480x191.png 480w\" sizes=\"auto, (max-width: 602px) 100vw, 602px\" \/><\/figure>\n\n\n\n<p>Now it looks for csharp razor files that make sense and are performance-friendly.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"conclusion\">Conclusion<\/h2>\n\n\n\n<p>In this post, we have discussed the following six tips, which can be easily applied to any ASP.NET application.<\/p>\n\n\n\n<p class=\"CxSpFirst\">1 &#8211;<span style=\"line-height: normal;\"><span style=\"font-family: Times New Roman;\"><span style=\"font-size: 7pt;\">&nbsp;&nbsp; <\/span><\/span><\/span>Kernel mode Cache<\/p>\n\n\n\n<p class=\"CxSpMiddle\">2 &#8211; Pipeline mode<\/p>\n\n\n\n<p class=\"CxSpMiddle\">3 &#8211;<span style=\"line-height: normal;\"><span style=\"font-family: Times New Roman;\"><span style=\"font-size: 7pt;\">&nbsp; <\/span><\/span><\/span>Remove unused modules<\/p>\n\n\n\n<p class=\"CxSpMiddle\">4 &#8211;<span style=\"line-height: normal;\"><span style=\"font-family: Times New Roman;\"><span style=\"font-size: 7pt;\">&nbsp;&nbsp; <\/span><\/span><\/span>runAllManagedModulesForAllRequests<\/p>\n\n\n\n<p class=\"CxSpMiddle\">5 &#8211;<span style=\"line-height: normal;\"><span style=\"font-family: Times New Roman;\"><span style=\"font-size: 7pt;\">&nbsp; <\/span><\/span><\/span>Don\u2019t write in wwwroot<\/p>\n\n\n\n<p class=\"CxSpLast\">6 &#8211;<span style=\"line-height: normal;\"><span style=\"font-family: Times New Roman;\"><span style=\"font-size: 7pt;\">&nbsp; <\/span><\/span><\/span>Remove unused view engines and language<\/p>\n\n\n\n<p>In next post of the series, we will discuss five more tips which will work as a performance booster for the applications.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"\/downloads\/request\/00000000-0000-0000-0000-000000005656?p=asp.net\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" src=\"https:\/\/download.infragistics.com\/marketing\/Blog-in-content-ads\/ASP.NET\/Blog-in-content-ASP-650x200.jpg\" alt=\" \"\/><\/a><\/figure>\n\n\n\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Building and hosting a web application on a web server is insanely easy with ASP.NET and IIS. However, many opportunities and hidden configurations can be tweaked to make it a high-performance web application. In this series post, we will discuss some of the most unused or ignored tricks that can be easily applied to any web application.<\/p>\n","protected":false},"author":21,"featured_media":1219,"comment_status":"publish","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17],"tags":[],"class_list":["post-649","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-how-to"],"_links":{"self":[{"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/posts\/649","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/comments?post=649"}],"version-history":[{"count":4,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/posts\/649\/revisions"}],"predecessor-version":[{"id":1998,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/posts\/649\/revisions\/1998"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/media\/1219"}],"wp:attachment":[{"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/media?parent=649"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/categories?post=649"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.infragistics.com\/blogs\/wp-json\/wp\/v2\/tags?post=649"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}