ASP.NET MVC Performance Using Razor View Engine

In this article, you will learn about ASP.NET MVC performance using Razor View Engine.

Introduction

This article introduces how to use only the Razor View Engine rather than using both Razor and ASPX View Engine. By default, ASP.NET MVC supports both Razor View Engine and ASPX View Engine. The ASP.NET MVC also supports third party View Engines, such as Spark View Engine and Nhaml (enamel) but it is highly recommended that you don’t use third party View Engines until and unless the application has specific requirements for such kind. The View Engine is responsible to render a view in html, in the browser.

By default, the ASP.NET MVC is configured in such a way that it begins searching for the views that match the Web Form View Engine first. After that, it searches the views that match the Razor View Engine's naming conventions.

Request for a view
Figure 1: Request for a view

Let’s see an example to understand how MVC searches a view that matches the view engine’s naming convention. We create a controller with a name HomeController, as per the following code snippet.

  1. using System.Web.Mvc;  
  2.   
  3. namespace ViewEngine.Controllers  
  4. {  
  5.     public class HomeController : Controller  
  6.     {  
  7.         public ActionResult Index()  
  8.         {  
  9.             return View();  
  10.         }         
  11.     }  
  12. }  
We don’t create view for the Index action method and run the application. The result shows, as follows.
Searches for view
Figure 2: Searches for view

The figure 2 shows that MVC begins a search for a view that matches the Web Form View Engine’s naming convention first. After that, it searches what matches Razor View Engine’s naming convention. So, if we use the Razor View Engine only in the application, we must remove the Web Form View Engine to improve application performance.

Remove Unused View Engine

An application doesn’t have specific requirements to use both the Web Form View Engine and the Razor View Engine. So, we remove one. As Razor Engine is an advanced view engine that was introduced with MVC3, most of today’s applications use it rather than Web Form View Engine. To remove the Web Form View Engine, we first remove all the view engines, using clear method. Thereafter, we add the Razor View Engine in the application. We update Application_Start method of Global.asax file to remove unused view engines, as per the following code snippet.
  1. protected void Application_Start()  
  2.    {  
  3.        AreaRegistration.RegisterAllAreas();  
  4.        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);  
  5.   
  6.        //Remove All View Engine  
  7.        ViewEngines.Engines.Clear();  
  8.        //Add Razor View Engine  
  9.        ViewEngines.Engines.Add(new RazorViewEngine());  
  10.   
  11.        RouteConfig.RegisterRoutes(RouteTable.Routes);  
  12.        BundleConfig.RegisterBundles(BundleTable.Bundles);  
  13.    }  
Now, we run the application again. This time, we see that MVC searches the view that matches the Razor View Engine’s Naming convention only. The below figure shows we are using the Razor View Engine only, for this application.

The Razor View Engine only
Figure 3: The Razor View Engine only

The above figure shows that MVC searches the view for both C# and VB but if the application doesn’t use both languages, then we should develop custom view engine as per the specific language.

Custom View Engine for C# in MVC

As we can still see view searches for both programming languages (C# and VB) but most of the applications use single programming language, either C# or VB. That’s why we develop a custom view engine for one programming language. As an example, we choose C# .

The Razor View Engine has location properties having predefined values. These location properties control how view templates are located. These locations for master, regular, and partial, view are both in a default project configuration and when areas are used.

The following table shows location properties in the Razor View Engine, with predefined values.
 
Sr No Property Default location format
1AreaMasterLocationFormats~/Areas/{2}/Views/{1}/{0}.cshtml
~/Areas/{2}/Views/Shared/{0}.cshtml
~/Areas/{2}/Views/{1}/{0}.vbhtml
~/Areas/{2}/Views/Shared/{0}.vbhtml
2AreaPartialViewLocationFormats~/Areas/{2}/Views/{1}/{0}.cshtml
~/Areas/{2}/Views/{1}/{0}.vbhtml
~/Areas/{2}/Views/Shared/{0}.cshtml
~/Areas/{2}/Views/Shared/{0}.vbhtml
3AreaViewLocationFormats~/Areas/{2}/Views/{1}/{0}.cshtml
~/Areas/{2}/Views/{1}/{0}.vbhtml
~/Areas/{2}/Views/Shared/{0}.cshtml
~/Areas/{2}/Views/Shared/{0}.vbhtml
4MasterLocationFormats~/Views/{1}/{0}.cshtml
~/Views/Shared/{0}.cshtml
~/Views/{1}/{0}.vbhtml
~/Views/Shared/{0}.vbhtml
5PartialViewLocationFormats~/Views/{1}/{0}.cshtml
~/Views/{1}/{0}.vbhtml
~/Views/Shared/{0}.cshtml
~/Views/Shared/{0}.vbhtml
6ViewLocationFormats~/Views/{1}/{0}.cshtml
~/Views/{1}/{0}.vbhtml
~/Views/Shared/{0}.cshtml
~/Views/Shared/{0}.vbhtml
7FileExtensions.cshtml, .vbhtml

As the table shows, there are a few location formats only rather than fully qualified paths. There are three placeholders which refer values as the following:

  1. The name of the view, as it is being invoked from the controller’s method.
  2. The controller name as it is used in the URL.
  3. The area name if specified.

As the ASP.NET MVC is an open source, it’s good that we can develop our custom view engine. Razor View Engine has location properties with predefined values, so our custom view engine inherits the RazorViewEngine class and assigns new values to these predefined location properties in the constructor, as per the following code snippet.

  1. using System.Web.Mvc;  
  2.   
  3. namespace ViewEngine.App_Start  
  4. {  
  5.     public class CSharpRazorViewEngine : RazorViewEngine  
  6.     {  
  7.         public CSharpRazorViewEngine()  
  8.         {  
  9.             AreaViewLocationFormats = new[]  
  10.              {  
  11.              "~/Areas/{2}/Views/{1}/{0}.cshtml",  
  12.              "~/Areas/{2}/Views/Shared/{0}.cshtml"  
  13.              };  
  14.             AreaMasterLocationFormats = new[]  
  15.              {  
  16.              "~/Areas/{2}/Views/{1}/{0}.cshtml",  
  17.              "~/Areas/{2}/Views/Shared/{0}.cshtml"  
  18.              };  
  19.             AreaPartialViewLocationFormats = new[]  
  20.              {  
  21.              "~/Areas/{2}/Views/{1}/{0}.cshtml",  
  22.              "~/Areas/{2}/Views/Shared/{0}.cshtml"  
  23.              };  
  24.             ViewLocationFormats = new[]  
  25.              {  
  26.              "~/Views/{1}/{0}.cshtml",  
  27.              "~/Views/Shared/{0}.cshtml"  
  28.              };  
  29.             MasterLocationFormats = new[]  
  30.              {  
  31.              "~/Views/{1}/{0}.cshtml",  
  32.              "~/Views/Shared/{0}.cshtml"  
  33.              };  
  34.             PartialViewLocationFormats = new[]  
  35.              {  
  36.              "~/Views/{1}/{0}.cshtml",  
  37.              "~/Views/Shared/{0}.cshtml"  
  38.              };  
  39.         }  
  40.     }  
  41. }  
We update Application_Start method of Global.asax file to call our developed custom C# Razor View Engine, as per the following code snippet.
  1. protected void Application_Start()  
  2.         {  
  3.             AreaRegistration.RegisterAllAreas();  
  4.             FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);  
  5.             //Remove All View Engine  
  6.             ViewEngines.Engines.Clear();  
  7.             //Add Custom C# Razor View Engine  
  8.             ViewEngines.Engines.Add(new CSharpRazorViewEngine());  
  9.             RouteConfig.RegisterRoutes(RouteTable.Routes);  
  10.             BundleConfig.RegisterBundles(BundleTable.Bundles);  
  11.         }  
Now, we run the application again and this time we see that MVC searches the view that matches the Custom C# Razor View Engine’s Naming convention only. The following figure shows we are using the Custom C# Razor View Engine only, for this application.

The Custom C# Razor View Engine Match
Figure 4: The Custom C# Razor View Engine Match

We can improve ASP.NET MVC application's performance using this way.

Difference Between Web Form View Engine and Razor View Engine
 
Though both the view engines are used to render view into html in the browser, but these have some differences, as follows:
 
Sr.No Web Form View Engine Razor View Engine
1A Web Form View Engine requires the code block to be closed properly otherwise it throws a run time exception.Razor does not require the code block to be closed. The Razor View Engine parses itself and it is able to decide at runtime which is a content element and which is a code element.
2It does not prevent Cross Site Scripting (XSS) attack. It prevents Cross Site Scripting (XSS) attacks by encoding the script or HTML tags, before rendering to the view.
3It does not support Test Driven Development (TDD) because it depends on the System.Web.UI.Page class to make the testing complex.The Razor Engine supports Test Driven Development (TDD).
4The namespace used by it is System.Web.Mvc.WebFormViewEngineThe namespace used by the Razor View Engine is System.Web.Razor
5The Razor View Engine is a bit slower than the Web Form View Engine
 
Other resources to improve ASP.NET MVC application performance