This is a migrated thread and some comments may be shown as answers.

forms very slow in Blazor WebAssembly

12 Answers 2804 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Carlos
Top achievements
Rank 1
Carlos asked on 13 Feb 2020, 08:05 AM

Hi,

I am having problems with Blazor WebAssembly.

In this form the response to the user is very bad and it stays frozen for several seconds when you try to write, and the controls take several seconds to react.

As you can see I do not have events that are launched continuously only the typical data-bindings.

That could be happening?

 

This is the sourc code:

 

@page "/ListaProyectos"

@using waProyectosPMO.Client.Services
@using waProyectosPMO.Client.Services.ModelDTOs
@using Telerik.Blazor
@using Telerik.Blazor.Components
@using System.Collections.ObjectModel
@using waProyectosPMO.Client.Resources
@using  Telerik.Blazor.Services

@inject IProyectoService servicioProyecto
@inject IAmbitoService servicioAmbito
@inject IEstadoService servicioEstado
@inject IDepartamentoService servicioDepartamento
@inject ITelerikStringLocalizer Localizer



<h1>Proyectos</h1>

<p>Lista de Proyectos de la aplicación</p>

@if (proyectos == null)
{
    <p><em>Cargando...</em></p>
}
else
{
    <TelerikGrid Data="@proyectos" Height="100%"
                 Pageable="true" Sortable="true" Groupable="true"
                 FilterMode="Telerik.Blazor.GridFilterMode.FilterRow"
                 Resizable="true" Reorderable="true" OnUpdate="@UpdateHandler" OnCreate="@CreateHandler" OnCancel="@CancelHandler">

        <GridColumns>
            <GridCommandColumn Width="120px">
                <GridCommandButton Command="Save" Icon="save" ShowInEdit="true"></GridCommandButton>
                <GridCommandButton OnClick="@((args)=> SeleccionarProyectoItem(args.Item as ProyectoItem))" Icon="edit"></GridCommandButton>
                @*<GridCommandButton Command="Edit" Icon="edit"></GridCommandButton>*@
                <GridCommandButton Command="Delete" Icon="delete" OnClick="@DeleteWithConfirmation"></GridCommandButton>
                <GridCommandButton Command="Cancel" Icon="cancel" ShowInEdit="true"></GridCommandButton>
            </GridCommandColumn>
            <GridColumn Field="@(nameof(ProyectoItem.ProyectoItemID))" Width="80px" Title="ID" Filterable="false" Editable="false" />
            <GridColumn Field="@(nameof(ProyectoItem.Nombre))" Title="Nombre" Width="300px" Groupable="false" />
            <GridColumn Field="@(nameof(ProyectoItem.DescAmbito))" Title="Ambito" Width="270px" Groupable="true">
                <EditorTemplate>
                    @{
                        CurrentlyEditedProyectoItem = context as ProyectoItem;
                        <TelerikDropDownList Data="@ambitos" @bind-Value="CurrentlyEditedProyectoItem.AmbitoID"
                                             TextField="Nombre" ValueField="AmbitoItemID" DefaultText="Elija un Ambito"
                                             Width="180px" PopupHeight="auto"></TelerikDropDownList>
                    }
                </EditorTemplate>
            </GridColumn>
            <GridColumn Field="@(nameof(ProyectoItem.DescEstado))" Title="Estado" Width="270px" Groupable="true">
                <EditorTemplate>
                    @{
                        CurrentlyEditedProyectoItem = context as ProyectoItem;
                        <TelerikDropDownList Data="@estados" @bind-Value="CurrentlyEditedProyectoItem.EstadoID"
                                             TextField="Nombre" ValueField="EstadoItemID" DefaultText="Elija un Estado"
                                             Width="250px" PopupHeight="auto"></TelerikDropDownList>
                    }
                </EditorTemplate>
            </GridColumn>
            <GridColumn Field="@(nameof(ProyectoItem.EsEstrategico))" Title="Estrateg. S/N" Width="100px" Groupable="true" />
            <GridColumn Field="@(nameof(ProyectoItem.Descripcion))" Title="Descripcion" Width="300px" Groupable="false" />
            <GridColumn Field="@(nameof(ProyectoItem.Objetivo))" Title="Objetivo" Width="300px" Groupable="false" />
            <GridColumn Field="@(nameof(ProyectoItem.Mejoras))" Title="Mejoras" Width="300px" Groupable="false" />
            <GridColumn Field="@(nameof(ProyectoItem.DescPropietario))" Title="Dep.Propietario" Width="270px" Groupable="true">
                <EditorTemplate>
                    @{
                        CurrentlyEditedProyectoItem = context as ProyectoItem;
                        <TelerikDropDownList Data="@departamentos" @bind-Value="CurrentlyEditedProyectoItem.PropietarioID"
                                             TextField="Nombre" ValueField="DepartamentoItemID" DefaultText="Elija un Departamento"
                                             Width="250px" PopupHeight="auto"></TelerikDropDownList>
                    }
                </EditorTemplate>
            </GridColumn>
            <GridColumn Field="@(nameof(ProyectoItem.NombrePropietario))" Title="Propietario" Width="270px" Groupable="true" />
            <GridColumn Field="@(nameof(ProyectoItem.Criticidad))" Title="Criticidad" Width="100px" Filterable="false" Groupable="false" />
            @*<GridColumn Field="@(nameof(ProyectoItem.Prioridad))" Title="Prioridad" Width="100px" Filterable="false" Groupable="false" />*@
            <GridColumn Field="@(nameof(ProyectoItem.ImpactoTiempos))" Title="Imp. Tiempos" Width="100px" Filterable="false" Groupable="false" />
            <GridColumn Field="@(nameof(ProyectoItem.ImpactoCalidad))" Title="Imp. Calidad" Width="100px" Filterable="false" Groupable="false" />
            <GridColumn Field="@(nameof(ProyectoItem.ImpactoInformes))" Title="Imp. Informes" Width="100px" Filterable="false" Groupable="false" />
            <GridColumn Field="@(nameof(ProyectoItem.ImpactoSeguridad))" Title="Imp. Seguridad" Width="100px" Filterable="false" Groupable="false" />
            <GridColumn Field="@(nameof(ProyectoItem.ImpactoCostes))" Title="Imp. Costes" Width="100px" Filterable="false" Groupable="false" />
            <GridColumn Field="@(nameof(ProyectoItem.ImpactoIngresos))" Title="Imp. Ingresos" Width="100px" Filterable="false" Groupable="false" />
            <GridColumn Field="@(nameof(ProyectoItem.ImpactoImagen))" Title="Imp. Imagen" Width="100px" Filterable="false" Groupable="false" />
            <GridColumn Field="@(nameof(ProyectoItem.ImpactoSostenibilidad))" Title="Imp. Sostenib." Width="100px" Filterable="false" Groupable="false" />
            <GridColumn Field="@(nameof(ProyectoItem.GestionDelCambio))" Title="Gest. Cambio" Width="100px" Filterable="false" Groupable="false" />
            <GridColumn Field="@(nameof(ProyectoItem.Riesgo))" Title="Riesgo" Width="100px" Groupable="false" Filterable="false" />
            <GridColumn Field="@(nameof(ProyectoItem.DescRiesgo))" Title="Desc Riesgo" Width="270px" Groupable="false" />
            <GridColumn Field="@(nameof(ProyectoItem.Oportunidad))" Title="Oportunidad" Width="100px" Filterable="false" Groupable="false" />
            <GridColumn Field="@(nameof(ProyectoItem.DescOportunidad))" Title="Desc Oportunidad" Width="270px" Groupable="false" />
            <GridColumn Field="@(nameof(ProyectoItem.FechaPeticion))" Title="F.Peticion" Width="150px" Groupable="false">
                <Template>
                    @((context as ProyectoItem).FechaPeticion?.ToString("dd/MM/yyyy"))
                </Template>
            </GridColumn>
            <GridColumn Field="@(nameof(ProyectoItem.FechaNecesidad))" Title="F.Necesidad" Width="150px" Groupable="false">
                <Template>
                    @((context as ProyectoItem).FechaNecesidad?.ToString("dd/MM/yyyy"))
                </Template>
            </GridColumn>
            <GridColumn Field="@(nameof(ProyectoItem.FechaInicio))" Title="F.Inicio" Width="150px" Groupable="false">
                <Template>
                    @((context as ProyectoItem).FechaInicio?.ToString("dd/MM/yyyy"))
                </Template>
            </GridColumn>
            <GridColumn Field="@(nameof(ProyectoItem.FechaProduccion))" Title="F.Produccion" Width="150px" Groupable="false">
                <Template>
                    @((context as ProyectoItem).FechaProduccion?.ToString("dd/MM/yyyy"))
                </Template>
            </GridColumn>
            <GridColumn Field="@(nameof(ProyectoItem.FechaCierre))" Title="F.Cierre" Width="150px" Groupable="false">
                <Template>
                    @((context as ProyectoItem).FechaCierre?.ToString("dd/MM/yyyy"))
                </Template>
            </GridColumn>
            <GridColumn Field="@(nameof(ProyectoItem.CosteEstimado))" Title="Coste" Width="150px" Filterable="false" Groupable="false" />
            <GridColumn Field="@(nameof(ProyectoItem.RetornoIngresosEstimado))" Title="Ingresos" Width="150px" Filterable="false" Groupable="false" />
            <GridColumn Field="@(nameof(ProyectoItem.PuntuacionTotal))" Title="Puntuación" Width="150px" Filterable="false" Groupable="false" />
        </GridColumns>
        <GridToolBar>
            @*<GridCommandButton Command="Add" Icon="add">Añadir Proyecto</GridCommandButton>*@
            <GridCommandButton OnClick="@((args)=> AnadirProyectoItem())" Icon="add">@Localizer[nameof(Messages.Grid_Create)]</GridCommandButton>
        </GridToolBar>
    </TelerikGrid>

    <ConfirmWindow OnConfirm="@DeleteCallback" Visible="@( ItemToDelete != null )" OnCancel="@( _ => ItemToDelete = null )"
                   ConfirmText="@( $" Desea realmente borrar el proyecto {ItemToDelete?.Nombre}" )"
                   ConfirmTitle="Confirmacion de borrado" />



}

<style>
    .ancho_texto {
        width: 507px;
        /*margin-top:10px;*/
    }
     .ancho_texto_400 {
        width: 400px;
        /*margin-top:10px;*/
    }
     .ancho_selector_peso_95 {
        width:90px!important;
        /*margin-top:5px;*/
    }
     .ancho_selector_peso_100 {
        width:100px!important;
    }

    .alto_texto_100 
    {
        height:100px;
    }
    .ancho_span_libre {
        width: auto;
        margin-right:10px;
    }
   
   
</style>

<TelerikWindow Width="1120px" Height="790px" Centered="true" Visible="@(selectedProyectoItem != null)" Modal="true">
    <WindowTitle>
        <strong>Editar Proyecto</strong>
    </WindowTitle>
    <WindowActions>
        <WindowAction Name="Close" />
    </WindowActions>
    <WindowContent>
        <EditForm Model="@selectedProyectoItem" >
            <div class="form-group ">
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Nombre
                    </label>
                    <TelerikTextBox @bind-Value="selectedProyectoItem.Nombre"  Width="1030px"></TelerikTextBox>
                </span>
            </div>
            <div class="form-group ">
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Ámbito
                    </label>
                    <TelerikDropDownList Data="@ambitos" @bind-Value="selectedProyectoItem.AmbitoID"
                                         TextField="Nombre" ValueField="AmbitoItemID" DefaultText="Elija un Ambito"
                                         Width="300px" PopupHeight="auto"></TelerikDropDownList>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Estado
                    </label>
                    <TelerikDropDownList Data="@estados" @bind-Value="selectedProyectoItem.EstadoID"
                                         TextField="Nombre" ValueField="EstadoItemID" DefaultText="Elija un Estado"
                                         Width="300px" PopupHeight="auto"></TelerikDropDownList>
                </span>

                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                   <label>
                    Es Estratégico:
                    <InputCheckbox @bind-Value="selectedProyectoItem.EsEstrategicoNotNull"></InputCheckbox>
                    </label>
                </span>

            </div>
            <div class="form-group ">
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Descripción
                    </label>
                    <InputTextArea Class="k-i-textarea ancho_texto alto_texto_100" @bind-Value="selectedProyectoItem.Descripcion"></InputTextArea>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Objetivo
                    </label>
                    <InputTextArea Class="k-i-textarea ancho_texto alto_texto_100" @bind-Value="selectedProyectoItem.Objetivo"></InputTextArea>
                </span>
            </div>
            <div class="form-group ">
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Mejoras
                    </label>
                    <InputTextArea Class="k-i-textarea ancho_texto" @bind-Value="selectedProyectoItem.Mejoras"></InputTextArea>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Dep.Propietario
                    </label>
                    <TelerikDropDownList Data="@departamentos" @bind-Value="selectedProyectoItem.PropietarioID"
                                         TextField="Nombre" ValueField="DepartamentoItemID" DefaultText="Elija un Departamento"
                                         Width="250px" PopupHeight="auto"></TelerikDropDownList>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Propietario
                    </label>
                    <TelerikTextBox @bind-Value="selectedProyectoItem.NombrePropietario" Width="245px"></TelerikTextBox>
                </span>
            </div>
            <div class="form-group ">
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Criticidad
                    </label>
                    <TelerikNumericTextBox Decimals="0" Format="#" Class="ancho_selector_peso_95" @bind-Value="selectedProyectoItem.Criticidad"></TelerikNumericTextBox>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Imp.Tiempo
                    </label>
                    <TelerikNumericTextBox Decimals="0" Format="#" Class="ancho_selector_peso_95" @bind-Value="selectedProyectoItem.ImpactoTiempos"></TelerikNumericTextBox>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Imp.Calidad
                    </label>
                    <TelerikNumericTextBox Decimals="0" Format="#" Class="ancho_selector_peso_95" @bind-Value="selectedProyectoItem.ImpactoCalidad"></TelerikNumericTextBox>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Imp.Informes
                    </label>
                    <TelerikNumericTextBox Decimals="0" Format="#" Class="ancho_selector_peso_95" @bind-Value="selectedProyectoItem.ImpactoInformes"></TelerikNumericTextBox>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Imp.Seguridad
                    </label>
                    <TelerikNumericTextBox Decimals="0" Format="#" Class="ancho_selector_peso_95" @bind-Value="selectedProyectoItem.ImpactoSeguridad"></TelerikNumericTextBox>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Imp.Costes
                    </label>
                    <TelerikNumericTextBox Decimals="0" Format="#" Class="ancho_selector_peso_95" @bind-Value="selectedProyectoItem.ImpactoCostes"></TelerikNumericTextBox>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Imp.Ingresos
                    </label>
                    <TelerikNumericTextBox Decimals="0" Format="#" Class="ancho_selector_peso_95" @bind-Value="selectedProyectoItem.ImpactoIngresos"></TelerikNumericTextBox>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Imp.Imagen
                    </label>
                    <TelerikNumericTextBox Decimals="0" Format="#" Class="ancho_selector_peso_95" @bind-Value="selectedProyectoItem.ImpactoImagen"></TelerikNumericTextBox>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Imp.Sostenib.
                    </label>
                    <TelerikNumericTextBox Decimals="0" Format="#" Class="ancho_selector_peso_95" @bind-Value="selectedProyectoItem.ImpactoSostenibilidad"></TelerikNumericTextBox>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Gest.Cambio
                    </label>
                    <TelerikNumericTextBox Decimals="0" Format="#" Class="ancho_selector_peso_95" @bind-Value="selectedProyectoItem.GestionDelCambio"></TelerikNumericTextBox>
                </span>
            </div>
            <div class="form-group ">
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Riesgo
                    </label>
                    <TelerikNumericTextBox Decimals="0" Format="#" Class="ancho_selector_peso_95" @bind-Value="selectedProyectoItem.Riesgo"></TelerikNumericTextBox>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Desc.Riesgo
                    </label>
                    <InputTextArea Class="k-i-textarea ancho_texto_400" @bind-Value="selectedProyectoItem.DescRiesgo"></InputTextArea>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Oportunidad
                    </label>
                    <TelerikNumericTextBox Decimals="0" Format="#" Class="ancho_selector_peso_95" @bind-Value="selectedProyectoItem.Oportunidad"></TelerikNumericTextBox>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Desc.Oportunidad
                    </label>
                    <InputTextArea Class="k-i-textarea ancho_texto_400" @bind-Value="selectedProyectoItem.DescOportunidad"></InputTextArea>
                </span>
            </div>
            <div class="form-group">
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        F.Petición
                    </label>
                    <TelerikDatePicker Format="dd/MM/yyyy" Width="115px" @bind-Value="selectedProyectoItem.FechaPeticion"></TelerikDatePicker>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        F.Necesidad
                    </label>
                    <TelerikDatePicker Format="dd/MM/yyyy" Width="115px" @bind-Value="selectedProyectoItem.FechaNecesidad"></TelerikDatePicker>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        F.Inicio
                    </label>
                    <TelerikDatePicker Format="dd/MM/yyyy" Width="115px" @bind-Value="selectedProyectoItem.FechaInicio"></TelerikDatePicker>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        F.Producción
                    </label>
                    <TelerikDatePicker Format="dd/MM/yyyy" Width="115px" @bind-Value="selectedProyectoItem.FechaProduccion"></TelerikDatePicker>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        F.Cierre
                    </label>
                    <TelerikDatePicker Format="dd/MM/yyyy" Width="115px" @bind-Value="selectedProyectoItem.FechaCierre"></TelerikDatePicker>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Coste Est.
                    </label>
                    <TelerikNumericTextBox Decimals="0" Format="#" Width="120px" @bind-Value="selectedProyectoItem.CosteEstimado"></TelerikNumericTextBox>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Ingresos Est.
                    </label>
                    <TelerikNumericTextBox Decimals="0" Format="#" Width="120px" @bind-Value="selectedProyectoItem.RetornoIngresosEstimado"></TelerikNumericTextBox>
                </span>
                <span class="k-textbox-container telerik-blazor ancho_span_libre">
                    <label class="k-label">
                        Puntuación Total
                    </label>
                    <TelerikNumericTextBox Decimals="0" Format="#" Width="115px" @bind-Value="selectedProyectoItem.PuntuacionTotal"></TelerikNumericTextBox>
                </span>
            </div>

            <div class="form-group">
                <div>
                    <TelerikButton Icon="save" Class="k-primary" OnClick="@EdicionGrabar">Grabar</TelerikButton>
                    <TelerikButton Icon="cancel" OnClick="@EdicionCancelar">Cancelar</TelerikButton>
                </div>
            </div>
        </EditForm>
    </WindowContent>
</TelerikWindow>

@code {

    public ProyectoItem originalProyectoItem { get; set; }
    public ProyectoItem selectedProyectoItem { get; set; }

    public ProyectoItem CurrentlyEditedProyectoItem { get; set; }

    //private ObservableCollection<ProyectoItem> proyectos;
    private List<ProyectoItem> proyectos;

    private List<AmbitoItem> ambitos;
    private List<EstadoItem> estados;
    private List<DepartamentoItem> departamentos;


    void LimpiarSelection()
    {
        originalProyectoItem = selectedProyectoItem = null;
    }

    public async Task EdicionGrabar()
    {
        if (originalProyectoItem == null)
        {
            await InsertarGrabar();
        }
        else
        {
            EstablecerProyectoItem(originalProyectoItem, selectedProyectoItem);
            await servicioProyecto.PutProyectoItem(originalProyectoItem);
            LimpiarSelection();
            this.StateHasChanged();
        }
    }

    public async Task InsertarGrabar()
    {
        selectedProyectoItem = CrearProyectoItem(selectedProyectoItem);
        await servicioProyecto.PostProyectoItem(selectedProyectoItem);
        await AddColeccion();
        LimpiarSelection();
    }

    public void EdicionCancelar()
    {
        LimpiarSelection();
    }

    void AnadirProyectoItem()
    {
        selectedProyectoItem = new ProyectoItem();

    }
    void SeleccionarProyectoItem(ProyectoItem p)
    {
        if (p != null)
        {
            originalProyectoItem = p;
            selectedProyectoItem = new ProyectoItem();
            EstablecerProyectoItem(selectedProyectoItem, p);
        }
        else
        {
            LimpiarSelection();
        }
        this.StateHasChanged();
    }


    protected override async Task OnInitializedAsync()
    {
        //proyectos = new ObservableCollection<ProyectoItem>(await servicioProyecto.GetProyectoItems());
        proyectos = await servicioProyecto.GetProyectoItems();
        ambitos = (await servicioAmbito.GetAmbitoItems()).OrderBy(o => o.Nombre).ToList();
        //await RellenarAmbitos();
        estados = (await servicioEstado.GetEstadoItems()).OrderBy(o => o.Nombre).ToList(); ;
        departamentos = (await servicioDepartamento.GetDepartamentoItems()).OrderBy(o => o.Nombre).ToList();
    }


    private ProyectoItem EstablecerProyectoItem(ProyectoItem original, ProyectoItem nuevo)
    {
        original.Ambito = (from a in ambitos where a.AmbitoItemID == nuevo.AmbitoID select a).FirstOrDefault<AmbitoItem>();
        original.Estado = (from e in estados where e.EstadoItemID == nuevo.EstadoID select e).FirstOrDefault<EstadoItem>();
        original.Propietario = (from d in departamentos where d.DepartamentoItemID == nuevo.PropietarioID select d).FirstOrDefault<DepartamentoItem>();
        if (nuevo.AmbitoID == -1)
        {
            original.AmbitoID = null;
            original.Ambito = null;
        }
        else
        {
            original.AmbitoID = nuevo.AmbitoID;
        }
        if (nuevo.EstadoID == -1)
        {
            original.EstadoID = null;
            original.Estado = null;
        }
        else
        {
            original.EstadoID = nuevo.EstadoID;
        }
        if (nuevo.PropietarioID == -1)
        {
            original.PropietarioID = null;
            original.Propietario = null;
        }
        else
        {
            original.PropietarioID = nuevo.PropietarioID;
        }

        original.Nombre = nuevo.Nombre;
        original.Descripcion = nuevo.Descripcion;
        original.CosteEstimado = nuevo.CosteEstimado;
        original.Criticidad = nuevo.Criticidad;
        original.DescOportunidad = nuevo.DescOportunidad;
        original.DescRiesgo = nuevo.DescRiesgo;
        original.EsEstrategico = nuevo.EsEstrategico;
        original.FechaCierre = nuevo.FechaCierre;
        original.FechaInicio = nuevo.FechaInicio;
        original.FechaNecesidad = nuevo.FechaNecesidad;
        original.FechaPeticion = nuevo.FechaPeticion;
        original.FechaProduccion = nuevo.FechaProduccion;
        original.GestionDelCambio = nuevo.GestionDelCambio;
        original.ImpactoCalidad = nuevo.ImpactoCalidad;
        original.ImpactoCostes = nuevo.ImpactoCostes;
        original.ImpactoImagen = nuevo.ImpactoImagen;
        original.ImpactoInformes = nuevo.ImpactoInformes;
        original.ImpactoIngresos = nuevo.ImpactoIngresos;
        original.ImpactoSeguridad = nuevo.ImpactoSeguridad;
        original.ImpactoSostenibilidad = nuevo.ImpactoSostenibilidad;
        original.ImpactoTiempos = nuevo.ImpactoTiempos;
        original.Mejoras = nuevo.Mejoras;
        original.NombrePropietario = nuevo.NombrePropietario;
        original.Objetivo = nuevo.Objetivo;
        original.Oportunidad = nuevo.Oportunidad;
        original.Prioridad = nuevo.Prioridad;
        original.PuntuacionTotal = nuevo.PuntuacionTotal;
        original.RetornoIngresosEstimado = nuevo.RetornoIngresosEstimado;
        original.Riesgo = nuevo.Riesgo;
        return original;
    }



    public async Task UpdateHandler(GridCommandEventArgs args)
    {
        args.IsCancelled = false;
        args.IsNew = false;
        ProyectoItem item = (ProyectoItem)args.Item;

        var proy = (from p in proyectos where p.ProyectoItemID == item.ProyectoItemID select p).FirstOrDefault<ProyectoItem>();

        if (proy != null)
        {
            EstablecerProyectoItem(proy, item);
        }
        ////perform actual data source operations here
        await servicioProyecto.PutProyectoItem(proy);

        ////var index = proyectos.FindIndex(i => i.ProyectoItemID == item.ProyectoItemID);

    }

    // para borrar con confirmacion
    ProyectoItem ItemToDelete;
    void DeleteWithConfirmation(GridCommandEventArgs args)
    {
        args.IsCancelled = true;//prevent the built-in delete operation from firing
        ItemToDelete = args.Item as ProyectoItem;
    }

    async void DeleteCallback()
    {
        if (ItemToDelete != null)
        {

            await CustomDelete(ItemToDelete);
        }
    }
    public async Task CustomDelete(ProyectoItem item)
    {
        //perform actual data source operation here
        ProyectoItem p = item;
        ItemToDelete = null;

        await servicioProyecto.DeleteProyectoItem(p);
        await RellenarColeccion();
    }

    private async Task RellenarColeccion()
    {
        List<ProyectoItem> lista = await servicioProyecto.GetProyectoItems();
        this.proyectos = null;
        this.StateHasChanged(); // to let the ui reevaluate
        await Task.Delay(10);
        this.proyectos = lista; // reassign your data
        this.StateHasChanged(); // to let the ui reevaluate
    }

    private async Task AddColeccion()
    {
        List<ProyectoItem> lista = await servicioProyecto.GetProyectoItems();
        this.proyectos = lista; // reassign your data
    }

    private ProyectoItem CrearProyectoItem(ProyectoItem p)
    {
        if (p.AmbitoID == -1)
        {
            p.AmbitoID = null;
        }
        if (p.EstadoID == -1)
        {
            p.EstadoID = null;
        }
        if (p.PropietarioID == -1)
        {
            p.PropietarioID = null;
        }
        return p;
    }
    public async Task CreateHandler(GridCommandEventArgs args)
    {

        ProyectoItem item = (ProyectoItem)args.Item;

        item = CrearProyectoItem(item);
        //perform actual data source operation here
        await servicioProyecto.PostProyectoItem(item);
        await AddColeccion();
    }

    public async Task CancelHandler(GridCommandEventArgs args)
    {
        ProyectoItem item = (ProyectoItem)args.Item;
    }

    private async Task RefrescarGrid()
    {
        var tmp = this.proyectos; // save for later
        this.proyectos = null; // set to something else -> null
        this.StateHasChanged(); // to let the ui reevaluate
        await Task.Delay(10);
        this.proyectos = tmp; // reassign your data
        this.StateHasChanged(); // to let the ui reevaluate
    }
}


12 Answers, 1 is accepted

Sort by
0
Accepted
Marin Bratanov
Telerik team
answered on 13 Feb 2020, 09:23 AM

Hello Carlos,

I suspect two things are going on:

  • The WASM flavor has performance issues with rendering that Microsoft need to solve, and this page looks like is is rather involved - it looks to me there are a lot of DOM elements on it (the grid rows alone would be around 4-5k), and such large amounts of markup can choke the browser, and re-rendering so much content is problematic for WASM Blazor to re-render.
  • We are working on improving the grid performance (independently from Microsoft's task) and you can Follow that task here - when it is done the grid should become faster as well: https://feedback.telerik.com/blazor/1450716-grid-selection-and-paging-slow

Ideas I can suggest you try to improve things:

  • I see that editing is done in a custom window, so you can try removing all the EditorTemplate instances. They should not be rendered and into play when the row is not in edit mode (and it should not ever be), but it may make the whole thing a little more lighweight.
  • Use ObservableCollection for the data source so the grid cna react to the data source change (clearing, or adding an item), like here: https://demos.telerik.com/blazor-ui/grid/observable-data. You should use that instead of the workarounds in RefrescarGrid and AddColeccion and RellenarColeccion.
  • Reduce the number of visible columns or rows to reduce the number of HTML elements that will be diffed and rendered by Blazor
  • See if you can hide the grid when an edit window is open (you already have a check for the presence of data, you can add one more for whether the Window is visible there) - this may reduce the weight of the page for Blazor and the form may start working faster. Or, you could event redirect the user to another edit page entirely through a NavigationManager.NavigateTo() method.
    • If the issue comes from too many DOM elements or a performance issue in the grid, this is very likely to help, and is one line of code (@if (proyectos == null || selectedProyectoItem != null)). I would appreciate it if you let me know what the result is if you try this.
  • Consider using a Server-side Blazor project for the time being, at least until Microsoft improve the performance and release the WASM flavor officially.

Since I could not run this (there are many missing dependencies - models, services) I am guessing a little just by reading the code. There may be something in the models that causes a slowdown when they change - the two-way binding alters their value on every keystroke, and if the entire model changes on every keystroke, this can slow things down as well. If the ideas above don't help, I would appreciate it if you can send me a very simple page that shows this issue - it should contain the models, a few hardcoded items for a grid data source so I can run and inspect it, so we can eliminate services and other application issues as the culprit.

 

Regards,
Marin Bratanov
Progress Telerik

 UI for Blazor
0
Carlos
Top achievements
Rank 1
answered on 13 Feb 2020, 08:50 PM

Hi,

Thanks a lot for your quick response :) !!. 

I will try somethings that you said to see if it improves.

The next week I will be on holidays but after that I will give feedback about your suggestions.

Regards.

 

 

 

 

0
Carlos
Top achievements
Rank 1
answered on 13 Feb 2020, 10:09 PM

Hi,

It's very strange. the problem exist too when the grid has few columns (ID and name only) and few records (1 or 2)

I don't understand why blazor has to refresh or todo a lot of things when the user is only typing letters in a textbox......

But I have tested  to hide the grid when ther user is editing or inserting a record and it works !!!

Thansk a lot.!!

It's  not perfect (I think that this has to be corrected by microsoft or telerik) but for now I can continue to develop the app.

Regards.

 

 

0
Accepted
Marin Bratanov
Telerik team
answered on 14 Feb 2020, 12:48 PM

Hi Carlos,

Thank you for your feedback. It is good that you have a workaround for the moment. Please follow the item I linked above (link) for updates on our performance (this does not mean that the WASM flavor does not need improvements on its own, but they are in Microsoft's domain).

I have used your code as base for a sample we will review internally to see if there is anything we can do about this as well. This is perhaps where I must note a key difference between our inputs and the "standard" ones that come with the framework - we bind the value on every keystroke (that is - the oninput DOM event) while the standard ones use the onblur (or onchange) event. Thus, ours update the model and validation on every keystroke, as opposed to blurring. Whlie this can cause a small performance hit in scenarios that are already slow (like WASM), it should not be a problem when the framework performance is OK (such as in server scenarios), but we believe that it makes for a much more intuitive experience for the user. That said, here's an article that shows how you can avoid that: https://docs.telerik.com/blazor-ui/knowledge-base/textbox-validate-on-change.

 

Regards,
Marin Bratanov
Progress Telerik

 UI for Blazor
0
Stefano
Top achievements
Rank 1
Iron
answered on 07 Nov 2020, 06:43 PM

Hi, 
I was struggling with a problem of unbearable slowness of  TimePicker and DatePicker, used inside an EditForm in a Client Blazor App, and this post is the only trace I found of such kind of problem. And this surprises me alot.

The only way I found to obtain a reasonable performance is to bind this controls to a variable outside the model, and to update the model only just before the final validation. In this way they are still visibly slow, but in a somewath acceptable measure.

In the console of the browser I see and incredible amount of re-rendering operations going on at every keystroke in the control. It seems to me that there is something wrong in how these controls work.

This is the razor code of my EditForm.

<TelerikWindow Width="600px" Modal="true" @bind-Visible="IsVisible" Class="absence-request-dialog">
        <WindowTitle> Richiesta di permesso </WindowTitle>
        <WindowContent>
            <TelerikTabStrip>
                <TabStripTab Title="Dati Richiesta">
                    <EditForm EditContext="@EditContext" class="absence-request-dialog__form grid-form">
                        <FluentValidator />
 
                        <div class="absence-request-dialog__base-voice">
                            <label for="@IdProvider.GetId("cboBaseVoices")">Causale</label>
                            <TelerikComboBox Id="@IdProvider.GetId("cboBaseVoices")" Data="BaseVoices" @bind-Value="Model.IdVoice"
                                             Placeholder="Selezionare una causale" Filterable="true" Width="100%"
                                             ValueField="Value" TextField="Label" />
                            <ValidationMessage For="@(() => Model.IdVoice)" />
                        </div>
 
                        <div class="absence-request-dialog__from-day">
                            <label for="@IdProvider.GetId("dateStart")">Giorno di inizio</label>
                            <TelerikDatePicker Id="@IdProvider.GetId("dateStart")" @bind-Value="_requestDateStart" />
                            <ValidationMessage For="@(() => Model.DateStart)" />
                        </div>
 
                        <div class="absence-request-dialog__to-day">
                            <label for="@IdProvider.GetId("dateEnd")">Giorno di fine</label>
                            <TelerikDatePicker Id="@IdProvider.GetId("dateEnd")" @bind-Value="_requestDateEnd" />
                            <ValidationMessage For="@(() => Model.DateEnd)" />
                        </div>
 
                        <div class="absence-request-dialog__from-time">
                            <label for="@IdProvider.GetId("timeStart")">Ora di inizio</label>
                            <TelerikTimePicker Id="@IdProvider.GetId("timeStart")" @bind-Value="_requestTimeStart" Format="t" />
                            <ValidationMessage For="@(() => Model.TimeStart)" />
                        </div>
 
                        <div class="absence-request-dialog__to-time">
                            <label for="@IdProvider.GetId("timeEnd")">Ora di fine</label>
                            <TelerikTimePicker Id="@IdProvider.GetId("timeEnd")" @bind-Value="_requestTimeEnd" Format="t" />
                            <ValidationMessage For="@(() => Model.TimeEnd)" />
                        </div>
 
                        <div class="absence-request-dialog__total-time">
                            <label for="@IdProvider.GetId("totalTime")">Tempo totale</label>
                            <TelerikTimePicker Id="@IdProvider.GetId("totalTime")" @bind-Value="_requestTotalTime" Format="t" />
                            <ValidationMessage For="@(() => Model.TotalTime)" />
                        </div>
 
 
                    </EditForm>
                </TabStripTab>
            </TelerikTabStrip>
 
            <DefaultWindowButtons OnClickOk="ConfirmDialog" OnClickCancel="CancelDialog" />
        </WindowContent>
    </TelerikWindow>

 

0
Stefano
Top achievements
Rank 1
Iron
answered on 07 Nov 2020, 09:28 PM
Hi, 
I have isolated the problem. 

To reproduce it:
- create in Visual Studio a Telerik C# Blazor Application choosing che CRUD template
- run it
- open the Form page
- in the date field change the year for 5 times
- every time the control operates slower than the preceding one until it becames almost unusable

If you remove the DatePicker from the form it works perfectly fast.

What can I do to make it work correctly in a form?
0
Marin Bratanov
Telerik team
answered on 09 Nov 2020, 06:29 PM

Hi Stefano,

Such behavior is not expected and I am not able to observe it on my end. I am attaching an app I made as instructed, and a short video of my test - I think I change the date around 20 times and I see no slowdown or difference in the component behavior. Am I missing something?

In the meantime, you can also check the following section of the documentation for performance optimization tips: https://docs.telerik.com/blazor-ui/troubleshooting/general-issues#slow-performance

If comparing against my sample and reviewing that article does not help you move forward, please open a support ticket and send us a sample that reproduces the Telerik component problem and a short video that shows how to reproduce it reliably, so we can investigate it.

Regards,
Marin Bratanov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
Stefano
Top achievements
Rank 1
Iron
answered on 09 Nov 2020, 06:50 PM
Hi Marin, 
thank you for your prompt response. 

I checked your video. Me too I have no problem changing the date in the way you does. The problem arises when I change it typing in the field. Try selecting the year part of the date and typing ten different years.
If I check the logging (verbose level), I see that at every stroke the amount of logs per stroke will grow. Wich would explain the growing slowness.
0
Marin Bratanov
Telerik team
answered on 09 Nov 2020, 07:04 PM

Thank you for getting back to me, Stefano.

I am attaching a new video where I type in the date portion (I use the on screen keyboard so it is visible when I click the buttons and when the effect happens on screen). On my end, after a lot of typing I start seeing some slowdown (it's around the 1 minute mark in the video where you can start noticing the lag). Is this the issue you observe?

 

Regards,
Marin Bratanov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
Stefano
Top achievements
Rank 1
Iron
answered on 09 Nov 2020, 08:27 PM
Hi Marin, 
thank you for your commitment in reproducing the problem.

Yes, this is what I observe on my side, with the only difference that after typing the year only ten times (with a real keyboard and without leaving the field) I observe a delay of around one second. Way faster and stronger than what I see in your video. I tried using the virtual keyboard and the problem is not so strong.

I attach a video in which I do the following: 
after having run only the client of you demo app, without debugging (ctrl+F5), in Edge, and having open the console, I start typing in rapid sequenza the years between 2001 and 2009. At 2004 the slag is really strong and I have to wait some second before seeing 2009 in the control.


C:\Users\mos\Documents\ShareX\Screenshots\2020-11
0
Marin Bratanov
Telerik team
answered on 10 Nov 2020, 08:35 AM

Hi Stefano,

Thank you for confirming this for me. On my end, there is no difference whether the physical or virtual keyboard is used and it does take about a minute to get into the lag. I think that this difference may be coming from a difference in the machines' performance between yours and mine - the WebAssembly flavor is highly dependent on that.

What I can also observe is that if you don't move the focus away from the input, the problem manifests faster for me, which is a difference from what I was doing.

I've logged this for review and you can Follow its status here: https://feedback.telerik.com/blazor/1494540-after-typing-in-the-date-input-its-performance-slows-down-in-webassembly. I've added your Vote to it on your behalf, and I've also added two workarounds you can consider and try.

 

Regards,
Marin Bratanov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
Trần
Top achievements
Rank 1
Iron
answered on 08 Feb 2022, 09:39 AM | edited on 08 Feb 2022, 09:41 AM

Hi Marin,

I'm having a problem with TelerikEditor, the response time after entering characters is very slow and I don't know where the cause comes from. I have attached Video and Code Page. Looking forward to your help.
Thank you.
Tags
General Discussions
Asked by
Carlos
Top achievements
Rank 1
Answers by
Marin Bratanov
Telerik team
Carlos
Top achievements
Rank 1
Stefano
Top achievements
Rank 1
Iron
Trần
Top achievements
Rank 1
Iron
Share this question
or