December 28, 2017

Avoid MVC Core Performance Penalty with Html.DisplayFor()

Recently when working with an ASP.NET Core project I had a page that was taking an unnecessarily long time to render. Looking at my code I couldn't figure out what I was doing wrong, the query returned fast, and although I was working to display about 1,000 rows in an HTML table, it shouldn't be taking seconds when the query returned in 22ms. Upon deeper review, I uncovered a bug that had been a silent killer of performance in multiple applications.

The Pattern

When using the default scaffolding templates to render "list" views within Visual Studio the template will output content using a snippet similar to the following.

@Html.DisplayFor(modelItem => item.ProductName)

This seems to be an innocent enough process. We want ASP.NET to make sure that we get a solid display based on the type, allowing us to use templates to control the display.

The Problem

Although this is the recommended approach, it is the use of Html.DisplayFor that is causing the slowdown. Doing a performance trace on the page load, you will find that all of the time spent is concentrated inside of this method, not something that we can optimize as a user.

Once I was able to fully track this down I submitted a bug report on GitHub. Others have confirmed the behavior, however, we don't yet have a solution in place.

The Workaround

The workaround for this is quite simple, rather than using Html.DisplayFor, simply reference your item directly. Such as the following from the prior example.

@item.ProductName

This simple process will work, and you should see a nice performance improvement. I seem to notice a performance impact anytime I have a view that renders more than 400-500 items using Html.DisplayFor. Your exact performance hit will vary depending on a number of factors. However, the workaround solution seems to be stable regardless of the number of elements.

Microsoft is looking at this item, and it is scheduled for triage, but for the time being, it might be helpful to keep an eye on this one! Hope it helps!

tags: Quick Tips, ASP.NET MVC, Performance, .NET Core, ASP.NET Core
comments powered by Disqus

Content provided in this blog is provided "AS-IS" and the information should be used at your own discretion.  The thoughts and opinions expressed are the personal thoughts of Mitchel Sellers and do not reflect the opinions of his employer.

Content Copyright

Content in this blog is copyright protected.  Re-publishing on other websites is allowed as long as proper credit and backlink to the article is provided.  Any other re-publishing or distribution of this content is prohibited without written permission from Mitchel Sellers.