Slow DisplayFor performance in ASP.NET Core MVC

Doddler

In my current application I'm generating a fairly lengthy table to display to the user. I've been seeing some serious performance issues with it, which I've tracked down to usage of @Html.DisplayFor, and I'm not entirely sure why.

Edit: I've replaced the code sample with a more concise and reproducible setup.

In order to isolate the issue, I have created a new asp.net core MVC project using all default settings in visual studio, with no authentication. I created a view model as such:

public class TestingViewModel
{
    public int Id { get; set; }
    public string TextValue1 { get; set; }
    public string TextValue2 { get; set; }
}

Then added a controller which fills the view model with data to pass to the view:

    public IActionResult TestThings()
    {
        var list = new List<TestingViewModel>();
        for(var i = 0; i < 1000; i++)
            list.Add(new TestingViewModel {Id = i, TextValue1 = "Test", TextValue2 = "Test2"});

        return View(list);
    }

The view is the bare minimum possible to display the data:

@model List<DisplayForTest.ViewModels.TestingViewModel>

@foreach (var item in Model)
{
    @Html.DisplayFor(m => item.Id)
    @Html.DisplayFor(m => item.TextValue1)
    @Html.DisplayFor(m => item.TextValue2)
}

When running this code, it takes over one second to run! The culprit is the DisplayFor. If I change the view as follows:

@model List<DisplayForTest.ViewModels.TestingViewModel>

@foreach (var item in Model)
{
    @item.Id
    @item.TextValue1
    @item.TextValue2
}

This renders in 13ms. It's clear DisplayFor is adding a huge amount of time to rendering... on my PC that's nearly 0.4ms per call. While that's not bad in isolation, it makes it a pretty bad choice for lists or other things.

Is DisplayFor really just that slow? Or am I using it incorrectly?

Will Ray

Is DisplayFor really just that slow? Or am I using it incorrectly?

It takes a bit of overhead to evaluate and execute lambda expressions. First the framework has to validate it, then evaluate it. I am speculating a bit here, but it seems likely this is where the performance concerns are coming from; both of these methods require reflection.

All of the other display methods I've played with (ValueFor, DisplayTextFor, etc.) have the same performance effect in your example.

I can't speak for the MVC team as to why it is used for the default scaffolding, but it does make sense to me. DisplayFor can handle both of the most common use cases (displaying the value of a property, and displaying the value of a property using a custom template), and performs reasonably well in most cases.

In this case, I don't see a problem with just using the raw value (basically .ToStringing it), or using it within an Html.Encode/Html.Raw method depending on what you're looking for.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related