JavaScript suele ser un activador de cambios visuales. A veces, realiza esos cambios directamente a través de manipulaciones de diseño y, otras veces, a través de cálculos que generan cambios visuales, como la búsqueda o la clasificación de datos. El código JavaScript de larga duración o mal programado puede ser una causa común de problemas de rendimiento, y debes intentar minimizar su impacto siempre que puedas.
Cálculo de estilo
Cambiar el DOM agregando y quitando elementos, cambiando atributos, clases o reproduciendo animaciones hace que el navegador vuelva a calcular los estilos de los elementos y, en muchos casos, el diseño de parte o de toda la página. Este proceso se denomina cálculo de estilo.
El navegador comienza a calcular los estilos creando un conjunto de selectores coincidentes para determinar qué clases, seudoselectores y IDs se aplican a un elemento determinado. Luego, procesa las reglas de estilo de los selectores coincidentes y determina qué estilos finales tiene el elemento.
El rol del nuevo cálculo de estilo en la latencia de interacción
La Interaction to Next Paint (INP) es una métrica de rendimiento del tiempo de ejecución centrada en el usuario que evalúa la capacidad de respuesta general de una página a las entradas del usuario. Mide la latencia de interacción desde que el usuario interactúa con la página hasta que el navegador renderiza el siguiente fotograma que muestra las actualizaciones visuales correspondientes en la interfaz de usuario.
Un componente importante de una interacción es el tiempo que tarda en renderizarse el siguiente fotograma. El trabajo de renderización que se realiza para presentar el siguiente fotograma se compone de muchas partes, incluido el cálculo de los estilos de la página que se produce justo antes del trabajo de diseño, pintura y composición. En esta guía, se explican los costos de cálculo de estilo, pero reducir cualquier parte de la duración total de la renderización de la interacción también reduce su latencia total.
Reduce la complejidad de tus selectores
Simplificar los selectores de CSS puede ayudar a acelerar los cálculos de estilo de tu página. Los selectores más simples hacen referencia a un elemento en CSS solo con un nombre de clase:
.title {
/* styles */
}
Sin embargo, a medida que crece cualquier proyecto, es probable que necesite CSS más complejos, y es posible que termines con selectores como este:
.box:nth-last-child(-n+1) .title {
/* styles */
}
Para determinar cómo se aplican estos estilos a la página, el navegador debe preguntar de manera efectiva: "¿Es este un elemento con una clase de title con un elemento superior de una clase de box que es el hijo n-ésimo menos 1 de su elemento superior?". El navegador puede tardar un tiempo en determinarlo. Para simplificar esto, puedes cambiar el selector para que sea un nombre de clase más específico:
.final-box-title {
/* styles */
}
Estos nombres de clase de reemplazo pueden parecer extraños, pero simplifican mucho el trabajo del navegador. En la versión anterior, por ejemplo, para que el navegador sepa que un elemento es el último de su tipo, primero debe saber todo sobre todos los demás elementos para determinar si hay elementos que vienen después que podrían ser el nth-last-child. Esto puede ser mucho más costoso en términos de procesamiento que hacer coincidir un selector con un elemento solo en función de su nombre de clase.
Reduce la cantidad de elementos a los que se les aplica un diseño
Otra consideración de rendimiento, y a menudo más importante que la complejidad del selector, es la cantidad de trabajo que debe realizarse cuando cambia un elemento.
En términos generales, el peor caso del costo de calcular el estilo de los elementos calculados es la cantidad de elementos multiplicada por el recuento de selectores, ya que el navegador debe verificar cada elemento al menos una vez con cada estilo para ver si coincide.
Los cálculos de estilo pueden dirigirse a algunos elementos directamente en lugar de invalidar toda la página. En los navegadores modernos, esto suele ser menos problemático porque el navegador no siempre necesita verificar todos los elementos que un cambio podría afectar. Por otro lado, los navegadores más antiguos no siempre están optimizados para este tipo de tareas. Cuando sea posible, debes reducir la cantidad de elementos invalidados.
Mide el costo de volver a calcular el diseño
Existen varias formas de medir el costo del recálculo de diseño en el navegador. Cada una de ellas depende de si deseas medirla en el navegador de tu entorno de desarrollo o si deseas medir cuánto tiempo lleva este proceso para los usuarios reales de tu sitio web.
Cómo medir el costo del nuevo cálculo de diseño en las Herramientas para desarrolladores de Chrome
Una forma de medir el costo de los recálculos de diseño es usar el panel de rendimiento en las Herramientas para desarrolladores de Chrome. Para comenzar, haz lo siguiente:
- Abre Herramientas para desarrolladores.
- Navega a la pestaña Rendimiento.
- Marca la casilla de verificación Selector stats (Estadísticas del selector) (opcional).
- Haz clic en Grabar.
- Interactúa con la página.
Cuando dejes de grabar, verás algo similar a la siguiente imagen:
La tira en la parte superior es un gráfico de llamas en miniatura que también muestra los fotogramas por segundo. Cuanto más cerca esté la actividad de la parte inferior de la tira, más rápido pintará los fotogramas el navegador. Si ves que el gráfico tipo llama se nivela en la parte superior con barras rojas por encima, significa que tienes trabajo que está causando marcos de ejecución prolongada.
Vale la pena analizar más de cerca los fotogramas de ejecución prolongada durante una interacción, como el desplazamiento. Si ves un bloque morado grande, acerca la actividad y selecciona cualquier trabajo etiquetado como Recalculate Style para obtener más información sobre el trabajo de nuevo cálculo de estilo potencialmente costoso.
Si haces clic en el evento, se mostrará su pila de llamadas. Si el trabajo de renderización se debió a una interacción del usuario, se destaca el código JavaScript que activó el cambio de diseño. También muestra la cantidad de elementos que afecta el cambio (poco más de 900 en este caso) y cuánto tardó el cálculo de estilo. Puedes usar esta información para comenzar a buscar una solución en tu código.
Si marcaste la casilla de verificación Selector stats en la configuración del panel Rendimiento antes de realizar un registro, el panel inferior del registro tendrá una pestaña adicional con el mismo nombre.
Este panel proporciona datos útiles sobre el costo relativo de cada selector, lo que te permite identificar los selectores CSS costosos.
Para obtener más información, consulta la documentación de CSS Selector Stats.
Mide el costo del nuevo cálculo de estilo para los usuarios reales
Si tienes curiosidad por saber cuánto tiempo tarda en producirse el recálculo de diseño para los usuarios reales de tu sitio web, la API de Long Animation Frames te brinda las herramientas necesarias para hacerlo. Los datos de esta API se agregaron a la biblioteca de JavaScript web-vitals, incluido el tiempo de recálculo de diseño.
Si sospechas que la demora en la presentación de una interacción es el principal factor que contribuye al INP de una página, deberás determinar cuánto tiempo se dedica a volver a calcular los estilos en la página. Para obtener más información, consulta cómo medir el tiempo de nuevo cálculo del diseño en el campo.