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
| Necesitas | Usa | Por qué |
|---|---|---|
| Avisar de que estás procesando: una sección entera carga datos y aún no hay nada que mostrar | DnzLoader | Indicador 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 contenido | DnzSkeleton | Esqueleto 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 antes | DnzDeferredContent | Muestra primero un esqueleto y monta el contenido real tras un retardo |
| Que un componente que puede fallar no rompa toda la página | DnzTryComponent | Captura la excepción de renderizado y muestra un contenido alternativo |
| Una espera de IA con texto explicativo | DnzIALoader | Icono 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ón | No 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ámetro | Tipo | Por defecto | Qué hace |
|---|---|---|---|
Horizontal | bool | false | false 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ámetro | Tipo | Por defecto | Qué hace |
|---|---|---|---|
Lines | int | 1 | Número de rectángulos (líneas). Ajústalo a las filas que esperas: una tarjeta 1, una lista 5, un formulario largo 20 |
Height | string | "1rem" | Alto de cada línea. Sube a "80px" para simular una tarjeta o un KPI |
Radius | string | "0.25rem" | Radio de las esquinas de cada rectángulo |
MaxWidth | string | "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ámetro | Tipo | Por defecto | Qué hace |
|---|---|---|---|
DelayMs | int | 500 | Milisegundos antes de montar el contenido real. 0 lo muestra sin espera; usa valores crecientes (300, 600) para escalonar secciones |
ChildContent | RenderFragment | El contenido pesado que se aplaza | |
LoadingContent | RenderFragment | null | Indicador de carga a medida mientras espera. Sin él, usa un DnzSkeleton |
Class | string | "" | 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ámetro | Tipo | Por defecto | Qué hace |
|---|---|---|---|
ChildContent | RenderFragment | El contenido que se renderiza dentro del límite de error. Obligatorio (EditorRequired) | |
ErrorContent | RenderFragment<Exception> | null | Contenido 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ámetro | Tipo | Por defecto | Qué hace |
|---|---|---|---|
Text | string | "Analizando con IA..." | Texto bajo el icono |
Relacionado
- Diálogos y ventanas:
DnzDialogLayouttraeIsLoadingyErrorTextpara el cuerpo de un diálogo - Tablas e informes: donde más rinden el diferido y los esqueletos al mostrar listados pesados
- KPIs y métricas: el caso de uso habitual de la carga progresiva con
DnzDeferredContent - Patrones de uso: ejemplos completos que combinan estos componentes con el SDK
- Componentes · DinaZen
- SDK .NET · Cliente Dinaup: trae los datos que estos componentes cubren mientras cargan