Improve
MVC View Lookup

Mar 21

Sitefinity supports MVC through widgets and the Feather framework. We get the freedom to place views where we wish and through MVC conventions, Sitefinity will go through and find them them for us. With that look up process there are some look-ups that we may never utilise such as widgets built on web forms engine so why bother looking for it.

MVC has a lot of conventions which reduces the amount of plumbing code we have to write. With that convention there can be some process overhead such as the lookup for the view location. Below is an example of the lookup locations and the order they are processed in Sitefinity. (I miss named a view to then get the lookup locations listed in my error log.)

~/Views/Products/ProductsXX.cshtml
~/Views/Shared/ProductsXX.cshtml
~/Frontend-Assembly/Pdr.HandleSolutions/Mvc/Views/Products/ProductsXX.cshtml
~/Frontend-Assembly/Pdr.HandleSolutions/Mvc/Views/Shared/ProductsXX.cshtml
~/Frontend-Assembly/Telerik.Sitefinity.Frontend/Mvc/Views/Products/ProductsXX.cshtml
~/Frontend-Assembly/Telerik.Sitefinity.Frontend/Mvc/Views/Shared/ProductsXX.cshtml
~/Views/Products/ProductsXX.aspx
~/Views/Products/ProductsXX.ascx
~/Views/Shared/ProductsXX.aspx
~/Views/Shared/ProductsXX.ascx
~/Frontend-Assembly/Pdr.HandleSolutions/Mvc/Views/Products/ProductsXX.aspx#Handle.aspx
~/Frontend-Assembly/Pdr.HandleSolutions/Mvc/Views/Products/ProductsXX.ascx#Handle.ascx
~/Frontend-Assembly/Pdr.HandleSolutions/Mvc/Views/Shared/ProductsXX.aspx#Handle.aspx
~/Frontend-Assembly/Pdr.HandleSolutions/Mvc/Views/Shared/ProductsXX.ascx#Handle.ascx
~/Frontend-Assembly/Telerik.Sitefinity.Frontend/Mvc/Views/Products/ProductsXX.aspx#Handle.aspx
~/Frontend-Assembly/Telerik.Sitefinity.Frontend/Mvc/Views/Products/ProductsXX.ascx#Handle.ascx
~/Frontend-Assembly/Telerik.Sitefinity.Frontend/Mvc/Views/Shared/ProductsXX.aspx#Handle.aspx
~/Frontend-Assembly/Telerik.Sitefinity.Frontend/Mvc/Views/Shared/ProductsXX.ascx#Handle.ascx
~/Views/Products/ProductsXX.vbhtml
~/Views/Shared/ProductsXX.vbhtml
~/Frontend-Assembly/Pdr.HandleSolutions/Mvc/Views/Products/ProductsXX.cshtml#Handle.cshtml
~/Frontend-Assembly/Pdr.HandleSolutions/Mvc/Views/Products/ProductsXX.vbhtml#Handle.vbhtml
~/Frontend-Assembly/Pdr.HandleSolutions/Mvc/Views/Shared/ProductsXX.cshtml#Handle.cshtml
~/Frontend-Assembly/Pdr.HandleSolutions/Mvc/Views/Shared/ProductsXX.vbhtml#Handle.vbhtml
~/Frontend-Assembly/Telerik.Sitefinity.Frontend/Mvc/Views/Products/ProductsXX.cshtml#Handle.cshtml
~/Frontend-Assembly/Telerik.Sitefinity.Frontend/Mvc/Views/Products/ProductsXX.vbhtml#Handle.vbhtml
~/Frontend-Assembly/Telerik.Sitefinity.Frontend/Mvc/Views/Shared/ProductsXX.cshtml#Handle.cshtml
~/Frontend-Assembly/Telerik.Sitefinity.Frontend/Mvc/Views/Shared/ProductsXX.vbhtml#Handle.vbhtml

That's 28 locations searched before giving up. You will notice that there is a lot of search locations that we are highly unlikely to be using such as the .aspx, .ascx and .vbhtml files. But there is a way to clean some of those up and get to the actual locations quicker.

First, in our Application_Start method of the global.ascx we can clear out all the Web Forms options with two lines of code.

ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new RazorViewEngine());

This then results in 17 search locations.

~/Views/Products/ProductsXX.cshtml
~/Views/Shared/ProductsXX.cshtml
~/Frontend-Assembly/Pdr.HandleSolutions/Mvc/Views/Products/ProductsXX.cshtml
~/Frontend-Assembly/Pdr.HandleSolutions/Mvc/Views/Shared/ProductsXX.cshtml
~/Frontend-Assembly/Telerik.Sitefinity.Frontend/Mvc/Views/Products/ProductsXX.cshtml
~/Frontend-Assembly/Telerik.Sitefinity.Frontend/Mvc/Views/Shared/ProductsXX.cshtml
~/Views/Products/ProductsXX.vbhtml
~/Views/Shared/ProductsXX.vbhtml
~/Frontend-Assembly/Pdr.HandleSolutions/Mvc/Views/Products/ProductsXX.cshtml#Handle.cshtml
~/Frontend-Assembly/Pdr.HandleSolutions/Mvc/Views/Products/ProductsXX.vbhtml#Handle.vbhtml
~/Frontend-Assembly/Pdr.HandleSolutions/Mvc/Views/Shared/ProductsXX.cshtml#Handle.cshtml
~/Frontend-Assembly/Pdr.HandleSolutions/Mvc/Views/Shared/ProductsXX.vbhtml#Handle.vbhtml
~/Frontend-Assembly/Telerik.Sitefinity.Frontend/Mvc/Views/Products/ProductsXX.cshtml#Handle.cshtml
~/Frontend-Assembly/Telerik.Sitefinity.Frontend/Mvc/Views/Products/ProductsXX.vbhtml#Handle.vbhtml
~/Frontend-Assembly/Telerik.Sitefinity.Frontend/Mvc/Views/Shared/ProductsXX.cshtml#Handle.cshtml
~/Frontend-Assembly/Telerik.Sitefinity.Frontend/Mvc/Views/Shared/ProductsXX.vbhtml#Handle.vbhtml

To remove the .vbhtml extensions requires us to make our own custom ViewEngine class.

public class SitefinityViewEngine : RazorViewEngine
{
    public SitefinityViewEngine()
    {
        base.MasterLocationFormats = 
                new string[] { "~/Views/{1}/{0}.cshtml",
                                "~/Views/Shared/{0}.cshtml" };
        base.PartialViewLocationFormats = 
                new string[] { "~/Views/{1}/{0}.cshtml",
                                "~/Views/Shared/{0}.cshtml",
                                "~/Mvc/Views/{1}/{0}.cshtml",
                                "~/Mvc/Views/Shared/{0}.cshtml" };
        base.ViewLocationFormats = 
                new string[] { "~/Views/{1}/{0}.cshtml",
                                "~/Views/Shared/{0}.cshtml" };
        base.FileExtensions = 
                new string[] { "cshtml" };
    }
}

This then results in 10 search locations.

~/Views/Products/ProductsXX.cshtml
~/Views/Shared/ProductsXX.cshtml
~/Frontend-Assembly/Pdr.HandleSolutions/Mvc/Views/Products/ProductsXX.cshtml
~/Frontend-Assembly/Pdr.HandleSolutions/Mvc/Views/Shared/ProductsXX.cshtml
~/Frontend-Assembly/Telerik.Sitefinity.Frontend/Mvc/Views/Products/ProductsXX.cshtml
~/Frontend-Assembly/Telerik.Sitefinity.Frontend/Mvc/Views/Shared/ProductsXX.cshtml
~/Frontend-Assembly/Pdr.HandleSolutions/Mvc/Views/Products/ProductsXX.cshtml#Handle.cshtml
~/Frontend-Assembly/Pdr.HandleSolutions/Mvc/Views/Shared/ProductsXX.cshtml#Handle.cshtml
~/Frontend-Assembly/Telerik.Sitefinity.Frontend/Mvc/Views/Products/ProductsXX.cshtml#Handle.cshtml
~/Frontend-Assembly/Telerik.Sitefinity.Frontend/Mvc/Views/Shared/ProductsXX.cshtml#Handle.cshtml

This should provide a bit of improvement in your View lookup time.

View Lookup Cache

When running a Release build the view look-ups will be cached for improved performance. But you can improve the default cache option by creating your own. You can look read this MSDN post, Optimizing ASP.NET MVC view lookup performance if you are interested in another performance tweak.


Darrin Robertson - Sitefinity Developer

Thanks for reading and feel free to comment
Darrin Robertson


Leave a comment
Load more comments

Make a Comment

Please type the code above

comment-avatar