Search code examples
javascriptc#.netblazorwebassembly

.Net Problem: Searching in .net table goes slow


I am working on a Blazor Wasm project, and I have a problem in the performance of searching in a table (my table now has 3500 elements, but in production it can have 10000). I have to increase performance and I don't know how to do it. whether to approach it from C# or Javascript.

Iam using MudBlazor Components.

The Table in question:

<Virtualize Context="item" OverscanCount="50" TItem="ArticuloDto" Items="lArticulos">
  @if(FilterArticuloFunc(item))
  {
    <tr class="d-flex pa-2" style="border-bottom: 1px solid var(--mud-palette-tertiary);">
      <div class="flex-grow-1 flex-shrink-1 align-self-stretch">
        <MudText Typo="Typo.body1" Style="word-break: break-all;">@item.Descripcion</MudText>
        <MudText Typo="Typo.body2" Color="Color.Secondary">Codigo: @item.Codigo</MudText>
      </div>
      <div class="flex-shrink-0">
        <MudText Typo="Typo.h1" Align="Align.Right">$@item.Precio</MudText>
        <MudText Typo="Typo.body2" Align="Align.Right" Color="@StockToColor(item.ExistenciaActual)">Stock: @item.Existencia</MudText>
      </div>
    </tr>
  }
</Virtualize>

The FilterFunc in question:

private bool FilterArticuloFunc(ArticuloDto element)
{
  if (string.IsNullOrWhiteSpace(searchProductText))
    return true;
  if (element.Codigo.Contains(searchProductText, StringComparison.OrdinalIgnoreCase))
    return true;
  if (element.Descripcion.Contains(searchProductText, StringComparison.OrdinalIgnoreCase))
    return true;
  return false;
}

Solution

  • I guess you have all the 3500 items loaded in memory. You fine with that?

    50 overscan items is maybe too much. But your problem is somewhere else.

    You do the filtering only on visible items, thus breaking the rule of same height of all items in virtualize component. If the height is different, it cannot count height of scroller properly. And it does a lot of rendering there.

    I would suggest to create second list of ArticuloDto (lArticulosFiltered) and plug that into the virtualize component (Items="lArticulosFiltered") and do the filtering like this:

    lArticulosFiltered = lArticulos.Where(x=>x.Codigo.Contains(searchProductText, StringComparison.OrdinalIgnoreCase) && x.Descripcion.Contains(searchProductText, StringComparison.OrdinalIgnoreCase))
    

    (on the beginning you have to assign ArticuloDto to lArticulosFiltered )

    You may hit another performance issues (for example you are doubling amount of memory needed to hold all items).