< Go Back to Homepage

ASP.NET MVC: Hidden Performance Problem with HtmlHelper.RenderPartial functions

by Andreas Grabner, Apr 22, 09

The problem that has been discovered in this blog entry was resolved – thanks to Simone. Read my follow up blog post that describes why I ran into this problem: http://blog.dynatrace.com/2009/04/23/aspnet-mvc-htmlhelperrenderpartial-caches-resolved-names-in-release-mode/

Original Post

There are some great blog entries about how to improve ASP.NET MVC Performance. Simone Chiaretta bloged about How to improve the performance of ASP.NET MVC web applications. One of his thoughts were on HtmlHelper.RenderPartial and that it can have a significant performance impact on your application. I ran across the same problem and I figured out why that is!

What is HtmlHelper.RenderPartial?

System.Web.Mvc.Html.RenderPartialExtension.RenderPartial extends the HtmlHelper class by offering the ability to render a partial view into your ASP.NET Web Page. The first string parameter allows you to provide a partial view name. This can be the name of an aspx or aspc file. The file can be in the same directory as the ASP.NET Page that calls RenderPartial or it can be in the Shared subdirectory. RenderPartial will make sure to find the correct view to render. Here is an example how it looks in the markup code:

Call to HtmlHelper.RenderPartial. Will ultimately render SearchBox.ascx

Call to HtmlHelper.RenderPartial. Will ultimately render SearchBox.ascx

What happens when a normal ASP.NET MVC Page is processed?

I am currently working with the project Kigg from CodePlex. Its a great application that makes extensive use of ASP.NET MVC. When browsing to the default page several things happen. ASP.NET processes the default page. The application uses a master page which also gets processed. Both – the master page and the default page contain calls to the HtmlHelper class to render certain controls like Menu, SearchBox, MembershipBox and more. Kigg uses RenderPartial by passing a partial name as first parameter. From the outside everything looks fine and it works great. You might be surprised to see the following view captured with dynaTrace:

Exceptions thrown by a single page request

Exceptions thrown by a single page request

When we drill into the PurePath we see that those exception are thrown by RenderPartial:

3 Exceptions thrown for each RenderPartial

3 Exceptions thrown for each RenderPartial

Why do we see this problem?

When passing a partial view name to the RenderPartial method – RenderPartial needs to resolve the partial view name to a physical file that will be loaded and rendered. In order to do this – the ViewEngine is used to resolve the name. The default ViewEngine for ASP.NET MVC Applications is System.Web.Mvc.WebFormViewEngine. In the constructor of this engine we can see the individual file patterns that are used to locate the partial view.

WebFormViewEngine search patterns

WebFormViewEngine search patterns

This location patterns are used in case a partial name is passed to the RenderPartial method. For every pattern – RenderPartial is calling a File.Exists to check the files existance – and throwing an exception in case the file does not exist. In the case of the PurePath shown above – the actual control that was referenced was stored in the ~/Views/Shared directory and had an .ascx extension. The first 3 attempts to locate the file with the other file patterns failed. The 4th succeeded and the control could be loaded.

The problem that we have though is that every page request is throwing many exceptions. Exceptions that are hidden for us developers and that don’t actually show a real problem with the application. But – the more exceptions that are thrown the more overhead you have. Imagine several hundred concurrent users on this front page. Every web request throws 16 exception (in this case) – making it several thousand exceptions every second if we expect some decent load. Exceptions – that cause overhead and degrade overall performance.

How can we solve it?

The easiest way to solve this is by providing the full name to the control that should be rendered. Instead of using

we can use

Conclusion

Frameworks like ASP.NET MVC make it easy to write applications. As with any framework it is essential to understand whats going on under the hood. Hidden exceptions can impact the overall performance. Without knowing about these exceptions its impossible to solve this problems that lead to the exceptions.

When specifying the full path, the ViewEngine is not going to resolve the name with the defined search locations but is using the full qualified filename as it is passed as parameter.

If you want more information on how to solve this and other problems on the .NET Platform you might also be interested in my latest White Papers about Continuous Application Performance for Enterprise .NET Systems

Share
  • Facebook
  • Reddit
  • Digg
  • del.icio.us
  • StumbleUpon
  • LinkedIn
  • MisterWong
  • Technorati
  • E-mail this story to a friend!
  • Google Bookmarks
  • DZone
  • FriendFeed
  • Ping.fm
  • Slashdot
  • Twitter

Related posts:

  1. ASP.NET MVC: HtmlHelper.RenderPartial caches resolved names in release mode In my previous blog post I described a performance problem...
  2. Exceptions: The Good and The Evil Exceptions are a great way to communicate error state back...
  3. Automated Performance Analysis: What’s going on in my ASP.NET or ASP.NET MVC Application? I’ve spent some time in the last weeks playing with different...
  4. ASP.NET: How to correctly comment markup code I am working with an ASP.NET MVC Application and had...
  5. ASP.NET GridView Performance ASP.NET offers a powerful GridView control that can be used...

Trackback

32 comments yet

  1. ASP.NET MVC: Hidden Performance Problem with HtmlHelper.RenderPartial functions…

    Thank you for submitting this cool story – Trackback from progg.ru…

  2. [...] Performance, Scalability and Architecture – Java and .NET … [...]

  3. Excellent post. Thanks for clarifying the RenderPartial process and providing the solution.

    Blog posts like this are great, please write some more .NET performance articles! :)

  4. Very good analysis and thanks for sharing it.

  5. ASP.NET MVC: Hidden Performance Problem with HtmlHelper.RenderPartial functions – dynaTrace Blog – Andreas Grabner…

    Thank you for submitting this cool story – Trackback from DotNetShoutout…

  6. This leaves me with a bad impression, like if hardcoding the view path will become a maintenance burden later.

    Can not WebFormViewEngine be configured to better match the reality of your applications, ie. search first (or maybe even only) .ascx files in ~/Views/Shared?

  7. @David
    Good point. I already tried that. Its another workaround to the problem. Here is a code snippet that modifies the WebFormViewEngine rule set. You can place it in your Application Start:

    IViewEngine viewEngine = ViewEngines.Engines[0];
    if (viewEngine is WebFormViewEngine)
    {
    WebFormViewEngine wfViewEngine = (WebFormViewEngine)viewEngine;
    System.Collections.Generic.List newViewLocationFormats = new System.Collections.Generic.List(wfViewEngine.ViewLocationFormats);
    newViewLocationFormats.Insert(0, “~/Views/Shared/{0}”);
    wfViewEngine.ViewLocationFormats = newViewLocationFormats.ToArray();
    wfViewEngine.PartialViewLocationFormats = wfViewEngine.ViewLocationFormats;
    }

    The {0} placeholder will be filled with the value you pass in RenderPartial. this now allows you to define “mycontrol.ascx” or “mypage.aspx” without having the framework trying both file extensions for you.

    HtmlHelper.RenderAction has a similar issue. I will cover that in another blog post.

  8. Are you sure you are not running in debug mode?

  9. [...] to Vote[FriendFeed] Performance, Scalability and Architecture – Java and .NET Application Performance Manag…Wednesday, April 22, 2009 from [...]

  10. [...] See original here: Performance, Scalability and Architecture – Java and .NET … [...]

  11. @Simone
    There is no difference in debug or release mode.
    Whenever you use a relative view name – the WebFormViewEngine tries to resolve it to a physical file based on the pre-set patterns

  12. @Andreas: have a look at my post.
    http://codeclimber.net.nz/archive/2009/04/22/how-to-improve-htmlhelper.renderpartial-performances-donrsquot-run-in-debug-mode.aspx
    It resolves to the path using the pre-sets, but then, after the first time, it is cached. So no “exception-raising falls” happens again.
    And this has been confirmed by Rudi as well

  13. @simone: That was my thought as well.

    @op: Have you measured the performance gain in a production environment? Hard-coding the view paths *is* a maintenance burden, and I would expect the performance gain under real conditions to be negligible.

  14. I wouldn’t recommend using the full physical path. It ties you too much to the physical structure of the views directory. Later on, suppose you want to swap out the view engine. Ideally, you wouldn’t have to change the view name, but you would have to change the view path.

    As Simone pointed out, the perf problem is almost certainly because you’re running in debug in which case view locations are not cached. We only cache in release mode.

  15. [...] ASP.NET MVC: Hidden Performance Problem with HtmlHelper.RenderPartial functions [...]

  16. Hi All

    Thanks for all your comments. You were right about the debug mode. I downloaded a sample app – compiled it in release but i missed the setting in the web.config file which was set to

    setting it to is now caching the entries only causing the exceptions the first time the name resolving takes place.

    Sorry for the confusion. Lesson learned: double check all settings in your configuration files.

    Thanks again

  17. [...] my previous blog post I described a performance problem that I thought I found in the HtmlHelper.RenderPartial method. It [...]

  18. No problem… glad everything is ok now :)

  19. btw, you should put a notice on this post as well… readers that reach this might not scroll down till the last comment :)

  20. [...] been quite some talk on HtmlHelper.RenderPartial() in ASP.NET MVC space which you will find over here and here. After reading those posts, I did an in depth analysis of the view location part, I am [...]

  21. Tracing through the code from BuildManagerWrapper.CreateInstanceFromVirtualPath, the HttpException is thrown from the System.Web.UI.Util.CheckVirtualFileExists method if the HostingEnvironment.VirtualPathProvider.FileExists method returns false.

    Adding a call to HostingEnvironment.VirtualPathProvider.FileExists(virtualPath) at the start of the FileExists method would avoid this exception, and should drastically improve the performance.

  22. Nice Blog…

  23. [...] to VoteASP.NET MVC: Hidden Performance Problem with HtmlHelper.RenderPartial functions (4/21/2009)Tuesday, April 21, 2009 from blog.dynatrace.comThere are some great blog entries about how to [...]

  24. [...] been quite some talk on HtmlHelper.RenderPartial() in ASP.NET MVC space which you will find over here and here. After reading those posts, I did an in depth analysis of the view location part, I am [...]

  25. This is specifically helpful as we’re going to publish a Beginning series book there may be some readers who are not aware of its level and target audience.

  26. Nice Post
    I am .Net developer in India
    I am looking for this
    It is informative and useful one
    Thanks for the help and keep posting nice articles

  27. [...] ASP.NET MVC: Hidden Performance Problem with HtmlHelper.RenderPartial functions Performance, Scalabi… blog.dynatrace.com/2009/04/22/aspnet-mvc-hidden-performance-problem-with-htmlhelperrenderpartial-functions – view page – cached #Performance, Scalability and Architecture – Java and .NET Application Performance Management (dynaTrace Blog) RSS Feed Performance, Scalability and Architecture – Java and .NET Application Performance Management (dynaTrace Blog) » ASP.NET MVC: Hidden Performance Problem with HtmlHelper.RenderPartial functions Comments Feed Performance, Scalability and Architecture – Java and .NET Application Performance Management (dynaTrace Blog) ASP.NET GridView Performance How to test jQuery enabled Apps using JSON with Visual Studio ASP.NET MVC: HtmlHelper.RenderPartial caches resolved names in release mode — From the page [...]

  28. Great stuff. Really interesting.
    Keep your great work going.

  29. [...] I do have several stories where this has happened. For more details on this check out my post on Hidden Performance Problems with HtmlHelper.RenderPartial I wrote about a year [...]

  30. Excellent post. Its always good to look for whats going on beneath. Thanks for sharing !!!!

  31. A distributed caching solution called NCache also seems to be good for asp.net performance. below is the link about how it works

    http://www.alachisoft.com/ncache/asp-net-performance-scalability.html

  32. Nice one. Well Thanks for sharing it and keep posting it.

Add your comment now