2

I have an MVC3 page that renders a view containing a table. The table has a column for each day of the month, and there are 7 rows, each representing a department of an organisation.

In each cell of the table, there is an input textbox, where the user must enter a numeric value representing energy usage.

The class model looks like this:

public class EnergySheet
{
    public DateTime Month { get; set; }
    public List<DepartmentValue> DepartmentValues { get; set; }
}

public class DepartmentValue
{
    public int DepartmentId { get; set; }
    public string DepartmentName { get; set; }
    public List<DayValue> DayValues { get; set; }
}

public class DayValue
{
    public DateTime Date { get; set; }
    public decimal EnergyUsage { get; set; }
}

And the views are rendered like this:

EnergySheet.cshtml:

@model EnergySheet

@using(Html.BeginForm()){
    <table>
        <tbody>
            @Html.EditorFor(x => x.DepartmentValues)
        </tbody>
    </table>
    <input type="submit" value="Save" />
}

DepartmentValue.cshtml:

@model DepartmentValue
<tr>
    @Html.EditorFor(x => x.DayValue)
</tr>

DayValue.cshtml

@model DayValue
<td>
    @Html.EditorFor(x => x.EnergyUsage)
</td>

The problem

This all renders fine, and the model binds correctly when posted back to the server. However, the problem is performance - the page takes 10-15 seconds to render for a grid containing around 200 input fields.

I've ensured that I'm running in release mode, and the Web.config has <compilation debug="false"> - so it shouldn't be a problem with view paths not being cached. I'm using a powerful enough machine - quad i7, 16GB, etc.

Attempted fix

I tried replacing the "automatic iteration" over the editor templates by explicitly specifying the view template names - ie, @Html.EditorFor(x => x.DepartmentValues) becomes @Html.EditorFor(x => x.DepartmentValues, "DepartmentValues") and @Html.EditorFor(x => x.DayValue) becomes @Html.EditorFor(x => x.DayValue, "DayValue"). This also means manually iterating over the collections within the templates - as explained in this post. This solves the performance problem - the page renders instantly - but all the automatic model binding is lost.

My question is - should the automatic rendering of editor templates really be this slow? Or am I doing something wrong? A page with just 200 input fields surely shouldn't tax the rendering engine this much?

Community
  • 1
  • 1
SLP
  • 311
  • 3
  • 11
  • No images, the table contains just input fields. – SLP Oct 31 '15 at 09:16
  • Suggestion: Try server side pagination if need urgent basis. – Divyek Oct 31 '15 at 14:31
  • 1
    Try to use a third-party grid, like: http://jquerygrid.net – ataravati Oct 31 '15 at 15:23
  • Divyek - good idea, but unfortunately it's a requirement that all days of the month are visible together at the same time, in a left-to-right scrollable panel. – SLP Nov 01 '15 at 08:21
  • ataravati - thanks for the suggestion re: jquerygrid. My issue here though is more about why the rendering is so slow using the standard MVC EditorFor helpers - considering that these are part of the framework, and I'm only showing a couple of hundred inputs, it seems strange that it is so slow. Especially when it performs very quickly if I explicitly iterate over the IEnumerable elements. – SLP Nov 01 '15 at 08:24
  • I'm not sure why it's so slow to render, without digging into the code and/or using some sort of profiler it's hard to say. Have you considered sticking with your "attempted fix" but also naming the elements so that they will get picked up for automatic model binding - the model binder just looks for certain patterns of names in the form submitted.... – Matt Roberts Nov 03 '15 at 09:26
  • @Matt - thanks, that's exactly what I ended up doing. When I added the MVC3 source code to my solution and debugged, I found that each input control took around 70ms to render - no problem when there are a handful of controls, but a non-starter when there are a few hundred. The bottleneck seems to be in the way the framework resolves which editor template to use for each model type - this doesn't seem to be cached effectively by the framework. Explicitly specifying the template name steps around the bottleneck. – SLP Nov 09 '15 at 09:36

0 Answers0