Ralentizar: ver lo que ocurre en trescientos milisegundos
El control de velocidad del panel, por qué a velocidad normal es imposible juzgar una animación, y qué defectos solo se ven al décimo de velocidad.
Una transición de interfaz dura entre doscientos y cuatrocientos milisegundos. En ese tiempo, un ojo humano percibe que algo se ha movido y forma una impresión general, y no puede hacer mucho más: no distingue si la curva era correcta, si dos elementos empezaron a la vez, si algo dio un salto de un píxel al terminar, o si un elemento apareció desde una posición equivocada. El control de velocidad del panel resuelve ese límite biológico, y con él aparecen defectos que llevaban meses en producción sin que nadie supiera nombrarlos.
- Usar el control de velocidad del panel y elegir el factor adecuado.
- Enumerar los defectos que solo son perceptibles a velocidad reducida.
- Ralentizar desde código cuando el panel no basta.
- Distinguir un defecto de la animación de un defecto de rendimiento.
El control
El panel ofrece varios factores de reproducción por debajo del normal. La reproducción afecta a las animaciones capturadas, así que se pueden observar tantas veces como haga falta sin volver a provocarlas.
La elección del factor no es indiferente.
La mitad de velocidad basta para juzgar la sensación general y la coordinación entre elementos. Es el factor de trabajo habitual.
Un cuarto es donde se aprecia la curva: si la aceleración es la correcta, si el final es demasiado brusco, si hay un tramo en el que parece que se para.
Un décimo es para buscar defectos concretos: saltos, parpadeos, cambios de posición al empezar o al terminar. A esta velocidad, un salto de dos píxeles que a velocidad normal es imperceptible se ve con total claridad.
Ralentizar no es lo mismo que aumentar la duración. Con el control del panel, la animación mantiene su definición intacta y solo se reproduce más despacio; si en lugar de eso multiplicas la duración en el código, cambias la relación entre la curva y el tiempo percibido, y algunas curvas se comportan de forma distinta. Para juzgar, ralentiza; para ajustar, cambia el valor.
Los seis defectos que solo se ven despacio
El salto inicial. El elemento aparece en una posición y salta inmediatamente a otra en el primer fotograma. Suele deberse a que el estado inicial de la animación no coincide con el estado que el elemento tenía antes de empezar. Es invisible a velocidad normal y produce una sensación de brusquedad que nadie sabe explicar.
El salto final. El mismo problema al revés: la animación termina en un valor y el estilo que queda aplicado es otro ligeramente distinto. La causa habitual es la falta de un modo de relleno adecuado, o una regla CSS que se aplica al terminar.
El parpadeo de subpíxel. El texto cambia de nitidez durante el movimiento porque el elemento se promueve a capa propia al empezar y vuelve al terminar. A velocidad normal se percibe como una vibración leve del texto.
La curva equivocada. Una animación que arranca demasiado rápido y frena de golpe, o que arranca lenta y acaba de golpe. La descripción que la gente da es “no se siente natural”, y a un cuarto de velocidad se ve exactamente en qué tramo está el problema.
El desajuste entre elementos. Dos elementos que deberían moverse solidariamente y llegan con unos milisegundos de diferencia. Produce una sensación de que la interfaz está mal montada.
El fotograma perdido. Un tirón puntual. Y este es el importante para diagnosticar, porque no es un defecto de la animación sino de rendimiento, y la distinción decide dónde buscar.
Distinguir defecto de animación de defecto de rendimiento
La regla es directa: si el defecto sigue ahí al ralentizar, es de la animación; si desaparece, es de rendimiento.
El motivo es que al ralentizar hay muchos más fotogramas disponibles para el mismo recorrido, así que un fotograma perdido se disimula. Un valor mal calculado, en cambio, sigue estando mal por muchos fotogramas que haya.
Cuando el diagnóstico apunta a rendimiento, la investigación continúa en otro sitio: en el perfil, buscando qué ocupa el hilo principal durante la animación, y en el panel de renderizado, comprobando si se está repintando lo que no debería.
Hay una comprobación intermedia muy rápida: si la animación solo afecta a transformación y opacidad y aun así va a tirones, el problema no es la animación sino que algo más está saturando el sistema. Si afecta a otras propiedades, el problema es la elección de propiedades.
Ralentizar desde código
El panel ralentiza lo que ha capturado. Cuando hace falta ralentizar algo que va a ocurrir —una animación de entrada que solo sucede una vez al cargar— es más práctico hacerlo desde código antes de provocarla.
// Control de velocidad global sobre todas las animaciones, incluidas las futuras
(() => {
let factorActual = 1;
const aplicar = (factor) => {
factorActual = factor;
for (const a of document.getAnimations()) a.updatePlaybackRate(factor);
};
// Interceptar las animaciones nuevas para que nazcan ya ralentizadas
const animarOriginal = Element.prototype.animate;
Element.prototype.animate = function (...args) {
const a = animarOriginal.apply(this, args);
if (factorActual !== 1) a.updatePlaybackRate(factorActual);
return a;
};
window.velocidad = (factor = 0.1) => {
aplicar(factor);
console.log('Velocidad de animacion:', factor + 'x');
console.log('Las animaciones nuevas tambien naceran a esta velocidad.');
};
window.velocidadNormal = () => { aplicar(1); console.log('Velocidad normal.'); };
window.restaurarAnimate = () => {
Element.prototype.animate = animarOriginal;
console.log('Interceptor de animate retirado.');
};
console.log('Usa velocidad(0.1) antes de recargar o de provocar la animacion.');
})();
Para las transiciones y animaciones declaradas en CSS, hay un camino todavía más simple que además sí afecta a las que ocurren durante la carga: una hoja de estilos inyectada que multiplique todas las duraciones.
// Ralentiza todas las transiciones y animaciones CSS de la pagina
(() => {
const estilo = document.createElement('style');
estilo.id = 'ralentizador';
estilo.textContent = `
*, *::before, *::after {
animation-duration: 4s !important;
animation-delay: 0s !important;
transition-duration: 4s !important;
transition-delay: 0s !important;
}`;
document.head.append(estilo);
window.quitarRalentizador = () => {
document.getElementById('ralentizador')?.remove();
console.log('Ralentizador retirado.');
};
console.log('Todo a cuatro segundos. Ejecuta quitarRalentizador() para volver.');
})();
Esta segunda técnica es más burda —cambia las duraciones en lugar de la velocidad de reproducción, y anula los retrasos, con lo que destruye el escalonamiento— pero tiene una virtud que la anterior no: funciona sobre animaciones que ocurren antes de que puedas capturarlas, incluidas las de entrada de la página.
Hay un riesgo profesional en esta técnica que conviene nombrar porque afecta a mucha gente que empieza a usarla: al ralentizar te enamoras de detalles que a velocidad real nadie va a ver, y el resultado suele ser alargar las animaciones para que se aprecien. Es un error muy comprensible. Cuando pasas veinte minutos ajustando una curva al décimo de velocidad, has visto ese movimiento con un nivel de detalle que ningún usuario tendrá jamás, y la tentación de darle tiempo para lucirse es enorme. Pero el usuario no está admirando tu transición: está intentando llegar a la pantalla siguiente, y cada milisegundo de animación es un milisegundo entre su intención y su resultado. Una interfaz con transiciones de seiscientos milisegundos se percibe como lenta aunque cada transición sea preciosa, y esa percepción de lentitud es indistinguible de la que produce un servidor lento. La disciplina que resuelve el conflicto tiene dos partes. La primera es separar los dos momentos con claridad: ralentiza para diagnosticar y corregir defectos, y vuelve siempre a velocidad real para decidir la duración. La duración es una decisión de experiencia y solo se puede tomar viendo el movimiento como lo verá el usuario, idealmente después de haber hecho otra cosa un rato para perder la familiaridad. La segunda es adoptar un presupuesto de duración y respetarlo: hay órdenes de magnitud bien establecidos —del orden de cien a doscientos milisegundos para respuestas directas a un toque, de doscientos a trescientos para transiciones de elementos, y algo más solo para cambios de pantalla completos— y salirse de ellos requiere una justificación, no una preferencia estética. Y hay una prueba final que resuelve casi todas las discusiones: quita la animación por completo y compara. Si la versión sin animación se siente mejor que la tuya, la animación está estorbando. Es una prueba incómoda porque muchas animaciones no la pasan, y precisamente por eso merece la pena hacerla: el movimiento en una interfaz tiene que ganarse su tiempo explicando algo, y el que no lo explica es un impuesto que el usuario paga en cada interacción.