Velocidad de interacción y latency UI
1) Qué es la velocidad de la interfaz
La velocidad no es solo cargar una página. Esta es la suma de cuatro retrasos:1. Input latency - Desde el gesto hasta el controlador de eventos.
2. Latencia de red: antes de la respuesta backend/kash.
3. Render latency - Procesamiento en el hilo principal (JS/CSS/layout/paint).
4. Animation latency - suavidad y estabilidad de fotogramas.
Objetivo: el usuario ve instantáneamente que la acción ha comenzado y hacia dónde se mueve el proceso; el resultado real viene previsiblemente.
2) Umbrales de percepción humana
≤ 50 ms - «relámpago» (eco de impresión, pulsación de tecla).
≤ 100 ms - «instantáneamente» (clic → respuesta visual).
≤ 200 ms - permitido para la mayoría de las reacciones de IU.
≤ 1000 ms - tolerable con progreso aparente/esqueleto.
3) Modelo RAIL y presupuestos objetivo
R (Respuesta): respuesta a la entrada
Click/tap → respuesta visual ≤ 100 ms.
Focus/hover → ≤ 80-120 ms.
A (Animation): suavidad
60 FPS ⇒ fotograma 16. 7 ms; operaciones pesadas para sacar fuera del marco.
Animamos sólo 'transformación '/' opacity'.
I (Idle): tareas de fondo
Dividimos en ranuras ≤ 50 ms, usamos ventanas idle.
L (Load): descargar
TTFB ≤ 200 ms, LCP ≤ 2. 5 s, INP ≤ 200 ms, CLS ≤ 0. 1.
4) KPI y alertas de velocidad
INP (Interaction to Next Paint): p75 <200 ms (bueno), 200-500 (necesario mejorar).
Long Tasks (> 50 ms): porcentaje de fotogramas con LT <5%.
TTFB p75 <200 ms (caché/edge), LCP p75 <2. 5 con.
First User Feedback (FUF): tiempo hasta la primera confirmación visual de la acción ≤ 100 ms.
Tiempo de uso para formularios: ≤ 1 desde antes de escribir el primer campo.
5) Patrones de respuesta instantánea UX
1. Actualizaciones optimistas: cambiamos la IU a la vez (balance/apuesta/me gusta), retrocedemos en caso de error.
2. Esqueletos en lugar de espinilla si se conoce la estructura.
3. Progreso/etapas: barra de progreso determinista si se conoce la longitud del proceso.
4. Pistas locales: tostadas instantáneas/« Enviar »... ≤ 100 ms.
5. Precarga en intención: hover/visibilidad → 'prefetch '/' preload'.
6) Técnicas para reducir los retrasos
6. 1 Input → Render
Filma 300 ms delay en los móviles: '<meta name = «viewport» content = «width = device-width, initial-scale = 1»>'.
Los oyentes passive para skroll/tacha son: 'addEventListener (' touchstart ', handler, {passive: true})'.
Procesamiento de clics - en una microempresa o 'requestAnimationFrame' para obtener rápidamente la confirmación.
Evite layout-thrash: leer/escribir layout - batear.
6. 2 JS y flujo principal
Separar las bandas (code-splitting), cargar a lo largo de las rutas.
Computación pesada → Web Worker.
Use el 'scheduler. postTask '/' requestIdleCallback 'para tareas de fondo.
CSS crítico - en línea; JS с `defer`/`async`.
Virtualización de listas, 'content-visibility: auto', 'contain: content'.
6. 3 Render y animaciones
Animar 'transformación/opacity'; no anime 'height/left/box-shadow' en cientos de elementos.
'will-change' poner temporalmente antes de la animación; limpiar después.
Sprites/vector en lugar de enormes PNG; evite el blur pesado.
6. 4 Red y caché
Edge-кеш (CDN), `cache-control`, `stale-while-revalidate`.
Preconnect a dominios críticos; Early Hints (103), HTTP/2/3.
Prefetch por intención (hover/viewport).
Streaming/SSR + hidratación progresiva/islas.
7) Debowns/trottling y colas
Debowns - para buscar durante la entrada (150-300 ms).
Trottling - para skroll/resize (100-200 ms).
Colas/marchas de actualizaciones de UI en eventos frecuentes (datos en vivo).
js const debounce = (fn, ms=200)=>{let t; return (...a)=>{clearTimeout(t); t=setTimeout(()=>fn(...a),ms)}}
const throttle = (fn, ms=120)=>{let t=0; return (...a)=>{const n=Date. now(); if(n-t>ms){t=n; fn(...a)}}}
8) Patrones de descarga y retroalimentación
Skeleton → Content (sin cizalladuras, alturas fijas).
Shimmer 1200-1600 ms, amplitud ≤ 20%.
Una tarjeta optimista: una vista previa gris + texto - sustituida cuando llegan los datos.
Error: banner retry corto, llaves idempotency para repeticiones.
9) Estrategias de red para una respuesta rápida
Acciones críticas (tasa/pago):- confirmación de IU de inmediato (optimista), backend - idempotent;
- cuando el tiempo de espera (3-5 c) muestra el estado «recibido, procesado» + retratos de fondo;
- WebSocket/SSE para estados, backoff 1-2-4-8 con.
Datos previos: caché warm-up programado, prefetch de rutas populares.
Edge funciones: validaciones/agregaciones más cercanas al usuario.
10) Código-snippets de UI rápido
Respuesta instantánea a un clic (feedback antes de la respuesta de red):js btn. addEventListener('click', () => {
btn. classList. add ('is-busy') ;//requestAnimationFrame instant visual response (async () => {
try {
const res = await fetch('/api/action', { method: 'POST', body: payload });
if (!res.ok) throw new Error('fail');
btn. classList. add('is-done');
} catch {
btn. classList. remove('is-busy'); btn. classList. add('is-error');
}
});
});
Prefetch por intención (hover/viewport):
js const prefetch = url => fetch(url, { credentials:'include', priority:'low' }). catch(()=>{});
document. querySelectorAll('a[data-prefetch]'). forEach(a=>{
a. addEventListener('mouseenter', () => prefetch(a. href), { once:true });
const io=new IntersectionObserver(e=>{ if(e[0].isIntersecting){prefetch(a. href); io. disconnect();} });
io. observe(a);
});
CSS para animaciones «baratas» y skeleton:
css
.btn. is-busy { pointer-events:none; }
.skeleton { position:relative; background: var(--bg-elevated); overflow:hidden; }
.skeleton::after {
content:""; position:absolute; inset:0;
background: linear-gradient(90deg, transparent, rgba(255,255,255,.12), transparent);
animation: shimmer 1. 4s infinite;
}
@keyframes shimmer { from { transform: translateX(-100%);} to { transform: translateX(100%);} }
11) Diagnóstico y monitoreo
Campo: RUM (métricas de campo) p75 por país/red/dispositivo.
Trace click: 'input → handler → network → paint'.
Marcando «zonas rojas»: marcadores de Long Task, tiempo de bloqueo, lista de ruta lenta.
Alertas de degradación INP/LCP/TTFB.
Pruebas de script: registro de tiempo de referencia «clic → cambio DOM».
12) Especificidad de iGaming
Puja/compra:- IU: fijación instantánea del estado del botón (pressed → busy), toma - tostado «Aceptado».
- Backend: idempotent clave de apuesta; estado - a través de WebSocket; tiempo de espera → «pending» transparente.
- UI-presupuesto: FUF ≤ 100 ms, confirmación final ≤ 1 s (si es más largo - mostrar temporizador/causa).
- Aceleración ≤ 200 ms, rotación uniforme, atenuación 300-500 ms; sin ciclos interminables.
- Tapones de ganancia - sin estroboscópico, texto/suma legible (AAA).
- Parches Delta una vez cada 250-1000 ms, batcheo;
- diff visual (flecha/color/grosor) sin saltos layout;
- antirrobo de actualizaciones en hover/focus.
- aumento de la cuenta de batches 40-60 ms, cifras tabulares;
- gorra de sticky, virtualización de cadenas.
13) Anti-patrones
No hay respuesta instantánea al clic (espera de red).
Animaciones pesadas 'filter/box-shadow' en cientos de elementos.
Un enorme JS-bandl> 1-2 MB en el camino crítico.
«Spinner en el vacío» más de 1-2 s sin progreso/esqueleto.
Leyendo/escribiendo layout en un tick (layout thrashing).
Hover-only funciones en móviles.
14) Señales de velocidad (sistema de diseño)
json
{
"latencyBudget": {
"tapFeedbackMs": 100,
"keyEchoMs": 50,
"hoverMs": 120,
"pressMs": 90,
"modalInMs": 240,
"toastInMs": 200
},
"webVitalsTargets": { "INP": 200, "LCP": 2500, "CLS": 0. 1, "TTFB": 200 },
"animation": {
"easing": { "std": "cubic-bezier(0. 2,0,0. 2,1)", "acc": "cubic-bezier(0. 4,0,1,1)" },
"duration": { "hover": 160, "active": 90, "overlay": 240 }
}
}
15) QA-check-list de velocidad
Respuesta
- Click/tap → respuesta visual ≤ 100 ms; entrada → eco ≤ 50 ms.
- No hay retardo de 300 ms en los móviles.
- INP p75 ≤ 200 ms; Long Tasks ≤ 5%.
Descargar
- TTFB ≤ 200 ms; LCP ≤ 2. 5 c; CLS ≤ 0. 1.
- Esqueletos/progreso en lugar de espinillas «colgantes».
Render
- Sólo 'transformación/opacity' en animaciones; no hay sombras «pesadas» en las matrices.
- content-visibility/virtualización para listas largas.
la Red
- Edge-caché, preconnect, prefetch por intención.
- Idempotencia y retraídas para la acción crítica.
A11y
- 'prefers-reduced-motion' apoyado.
- El contenido de hover está disponible por enfoque/teclado.
16) Documentación para el sistema de diseño
«Latency Budgets»: tabla de umbrales (tap, hover, modal, toast, formulario).
«Instant Feedback»: patrones de acción optimista + retroceso.
«Prefetch by Intent»: hyde y utilidades.
«Performance Playbook»: hojas de comprobación de perfiles y alertas RUM.
"Do/Don 't': ejemplos de escenarios rápidos/lentos con números.
Resumen breve
La velocidad de interacción es la respuesta instantánea + la entrega predecible del resultado. Mantenga 100 ms como un presupuesto sagrado para first-feedback, optimice la red (Edge/caché/prefetch), descargue el flujo principal, anime sólo las propiedades baratas y aplique patrones optimistas. Entonces la interfaz se siente viva, comprensible y sostenible - especialmente en escenarios iGaming con altas tasas y tiempo real.