Carga y rendimiento

Indicador de carga, esqueleto, contenido diferido y límite de error: qué pieza va en cada momento de la carga de una pantalla Blazor.

Cinco situaciones distintas, cinco componentes. Una acción en marcha que se está procesando: DnzLoader. Una interfaz sin datos todavía, con el hueco reservado: DnzSkeleton. Una sección costosa de renderizar que conviene aplazar: DnzDeferredContent. Un bloque que puede fallar al renderizar sin afectar a la página entera: DnzTryComponent. La espera de una operación de IA: DnzIALoader. Elige por el momento de la carga, no por el aspecto.

Cuál va en cada caso

NecesitasUsaPor qué
Avisar de que estás procesando: una sección entera carga datos y aún no hay nada que mostrarDnzLoaderIndicador de carga neutro centrado en el hueco mientras esperas a OnInitializedAsync
Avisar de que la interfaz aún no tiene datos: reservar el hueco con la forma del contenidoDnzSkeletonEsqueleto animado: el usuario ve el espacio que va a ocupar el contenido
Aplazar el renderizado de un bloque pesado para que la página cargue antesDnzDeferredContentMuestra primero un esqueleto y monta el contenido real tras un retardo
Que un componente que puede fallar no rompa toda la páginaDnzTryComponentCaptura la excepción de renderizado y muestra un contenido alternativo
Una espera de IA con texto explicativoDnzIALoaderIcono animado con el texto que le pases
Respuesta a una acción concreta del usuario (un botón, de 1 a 10 s)IsBusy=@variable en el botónNo es de esta familia: el indicador va en el propio botón

DnzLoader indica una operación en curso. DnzSkeleton indica que la interfaz aún se está montando. Si dudas, comprueba si hay datos en camino (DnzLoader) o si solo reservas el hueco a la espera (DnzSkeleton).


DnzLoader

Indicador de carga neutro para cuando una sección entera está cargando datos y aún no hay nada que mostrar. Es el patrón de "cargar en OnInitializedAsync y devolver pronto".

@if (Facturas.IsNull())
{
    <DnzLoader />
}
else
{
    <FacturasGridU Data=@Facturas />
}

@code {
    private List<FacturaDTO> Facturas { get; set; }

    protected override async Task OnInitializedAsync()
    {
        Facturas = await FacturasService.GetPendientesAsync();
    }
}

En barras o cabeceras estrechas, donde un indicador centrado no encaja, pasa Horizontal=true para la variante compacta de puntos:

<div class="d-flex align-items-center gap-2">
    <span>Sincronizando</span>
    <DnzLoader Horizontal=true />
</div>

Parámetros

ParámetroTipoPor defectoQué hace
Horizontalboolfalsefalse muestra el indicador vertical centrado en el hueco; true usa la variante horizontal compacta (tira de puntos)

DnzSkeleton

Reserva el hueco con rectángulos animados que imitan la forma del contenido que va a llegar. A diferencia de DnzLoader, el usuario ve cuántas líneas y qué tamaño va a ocupar.

@if (Movimientos.IsNull())
{
    <DnzSkeleton Lines="5" Height="0.9rem" />
}
else
{
    <MovimientosListaU Data=@Movimientos />
}

Combina varios esqueletos de distinto tamaño para imitar un encabezado más filas:

<DnzSkeleton Lines="1" Height="0.7rem" MaxWidth="55%" />
<DnzSkeleton Lines="2" Height="0.9rem" MaxWidth="100%" />

Parámetros

ParámetroTipoPor defectoQué hace
Linesint1Número de rectángulos (líneas). Ajústalo a las filas que esperas: una tarjeta 1, una lista 5, un formulario largo 20
Heightstring"1rem"Alto de cada línea. Sube a "80px" para simular una tarjeta o un KPI
Radiusstring"0.25rem"Radio de las esquinas de cada rectángulo
MaxWidthstring"100%"Ancho máximo del bloque. Limítalo ("400px", "55%") cuando el esqueleto no deba ocupar todo el ancho

DnzDeferredContent

Envuelve un bloque pesado y aplaza su montaje: durante el retardo muestra un esqueleto y, pasado ese tiempo, monta el contenido real. Sirve para que las páginas con muchas subvistas aparezcan antes, en lugar de bloquearse renderizando todo a la vez.

<DnzDeferredContent DelayMs="300">
    <VentasPorMesGraficoU Data=@Resumen />
</DnzDeferredContent>

En una página con muchas subvistas (un cuadro de mando, una ficha con varias pestañas, un listado con tarjetas pesadas), Blazor intenta renderizar todo en el primer paso. Envolviendo cada bloque caro en un DnzDeferredContent con retardos crecientes, lo importante aparece primero y el resto llega escalonado.

Carga progresiva en un cuadro de mando: los KPIs aparecen primero y las tarjetas pesadas llegan escalonadas.

<DnzDeferredContent DelayMs="0">
    <KpiSeccionU Data=@Kpis />
</DnzDeferredContent>

<DnzDeferredContent DelayMs="300">
    <DnzCard>
        <VentasPorMesGraficoU Data=@Ventas />
    </DnzCard>
</DnzDeferredContent>

<DnzDeferredContent DelayMs="600">
    <DnzCard>
        <TopClientesTablaU Data=@TopClientes />
    </DnzCard>
</DnzDeferredContent>

Si el esqueleto por defecto no sirve, pasa tu propio indicador de carga en LoadingContent:

<DnzDeferredContent DelayMs="800" Class="p-3">
    <ChildContent>
        <LineasFacturaU Data=@Lineas />
    </ChildContent>
    <LoadingContent>
        <DnzLoader />
    </LoadingContent>
</DnzDeferredContent>

Parámetros

ParámetroTipoPor defectoQué hace
DelayMsint500Milisegundos antes de montar el contenido real. 0 lo muestra sin espera; usa valores crecientes (300, 600) para escalonar secciones
ChildContentRenderFragmentEl contenido pesado que se aplaza
LoadingContentRenderFragmentnullIndicador de carga a medida mientras espera. Sin él, usa un DnzSkeleton
Classstring""Clase CSS para el contenedor del estado de carga ("p-3" para añadir margen interior)

DnzDeferredContent aplaza el renderizado, no la carga de datos. Si lo caro es la consulta, tráela en OnInitializedAsync y combina con DnzLoader o DnzSkeleton. El diferido solo reparte el coste de renderizar la interfaz.


DnzTryComponent

Envuelve un bloque que puede fallar al renderizar y captura la excepción para que no afecte a la página entera. Es un ErrorBoundary con un contenido alternativo opcional.

<DnzTryComponent>
    <GraficoExternoU Data=@Datos />
</DnzTryComponent>

Con contenido alternativo propio: el context es la Exception capturada, así que puedes mostrar el motivo.

<DnzTryComponent>
    <ChildContent>
        <WidgetTercerosU Config=@Config />
    </ChildContent>
    <ErrorContent>
        <RadzenAlert AlertStyle="AlertStyle.Danger" ShowIcon="true">
            No se pudo cargar el widget: @context.Message
        </RadzenAlert>
    </ErrorContent>
</DnzTryComponent>

El componente expone Recover() por @ref para reintentar el renderizado tras un fallo:

<DnzTryComponent @ref="boundary">
    <ChildContent>
        <WidgetTercerosU Config=@Config />
    </ChildContent>
    <ErrorContent>
        <div class="d-flex flex-column align-items-center gap-2 p-3">
            <span>El widget falló: @context.Message</span>
            <RadzenButton Text="Reintentar" Click=@(() => boundary.Recover()) />
        </div>
    </ErrorContent>
</DnzTryComponent>

@code {
    private DnzTryComponent boundary;
}

Parámetros

ParámetroTipoPor defectoQué hace
ChildContentRenderFragmentEl contenido que se renderiza dentro del límite de error. Obligatorio (EditorRequired)
ErrorContentRenderFragment<Exception>nullContenido alternativo si el ChildContent lanza una excepción. El context es la Exception. Sin él, no se muestra nada en su lugar

DnzIALoader

Indicador para operaciones de IA: icono animado con un texto debajo. Para la espera de un análisis, una extracción o una respuesta generada.

@if (_analizando)
{
    <DnzIALoader Text="Analizando el documento" />
}

Parámetros

ParámetroTipoPor defectoQué hace
Textstring"Analizando con IA..."Texto bajo el icono

Relacionado

En esta página