A lo largo de los años, la comunidad web ha acumulado una gran cantidad de conocimientos sobre la optimización del rendimiento web. Si bien cualquier optimización puede mejorar el rendimiento de muchos sitios, todas a la vez pueden ser abrumadoras y, en realidad, solo algunas de ellas se aplican a un sitio determinado.
A menos que el rendimiento web sea tu trabajo diario, es probable que no sea obvio qué optimizaciones tendrán el mayor impacto en tu sitio. Es probable que no tengas tiempo para todas, por lo que es importante que te preguntes cuáles son las optimizaciones más impactantes que puedes elegir para mejorar el rendimiento de tus usuarios.
La verdad sobre las optimizaciones de rendimiento es que no puedes juzgarlas solo por sus méritos técnicos. También debes considerar los factores humanos y organizativos que influyen en la probabilidad de que puedas implementar cualquier optimización determinada. Algunas mejoras de rendimiento pueden tener un gran impacto en teoría, pero, en realidad, pocos desarrolladores tendrán el tiempo o los recursos para implementarlas. Por otro lado, es posible que haya prácticas recomendadas de rendimiento de gran impacto que casi todos ya estén siguiendo. En esta guía, se identifican las optimizaciones de rendimiento web que tienen las siguientes características:
- Tener el mayor impacto en el mundo real
- Son relevantes y se aplican a la mayoría de los sitios.
- Son realistas para que la mayoría de los desarrolladores los implementen.
En conjunto, estas son las formas más realistas y eficaces de mejorar tus métricas de Métricas web esenciales. Si es la primera vez que trabajas con el rendimiento web o si aún no decides qué te dará el mayor retorno de la inversión, este es el mejor lugar para comenzar.
Interaction to Next Paint (INP)
Como la métrica más reciente de las Métricas web esenciales, la interacción a la siguiente pintura (INP) tiene algunas de las mayores oportunidades de mejora. Sin embargo, como muchos menos sitios superan el umbral de experiencias "buenas" en comparación con su predecesor obsoleto, es posible que seas uno de los muchos desarrolladores que aprenden a optimizar la capacidad de respuesta de la interacción por primera vez. Comienza con estas técnicas fundamentales para conocer las formas más eficaces de mejorar el INP.
1. Realiza una pausa con frecuencia para dividir tareas largas.
Las tareas son cualquier trabajo discreto que realiza el navegador, como la renderización, el diseño, el análisis, la compilación o la ejecución de secuencias de comandos. Cuando una tarea supera los 50 milisegundos de duración, se convierte en una tarea larga. Las tareas largas son problemáticas porque pueden impedir que el subproceso principal responda rápidamente a las interacciones del usuario.
Si bien siempre debes esforzarte por hacer el menor trabajo posible en JavaScript, puedes ayudar al subproceso principal dividiendo las tareas largas. Para ello, cede el subproceso principal con frecuencia, de modo que las actualizaciones de renderización y otras interacciones del usuario puedan ocurrir antes.
La API de Scheduler te permite poner en cola el trabajo con un sistema de prioridades. Específicamente, la API de scheduler.yield() divide las tareas largas y, al mismo tiempo, se asegura de que las interacciones se puedan controlar sin renunciar a su lugar en la cola de tareas.
Si divides las tareas largas, le das al navegador más oportunidades para realizar tareas críticas que bloquean a los usuarios.
2. Evita el código JavaScript innecesario
Los sitios web envían más JavaScript que nunca, y la tendencia no parece cambiar. Cuando envías demasiado JavaScript, creas un entorno en el que las tareas compiten por la atención del subproceso principal. Esto puede afectar la capacidad de respuesta de tu sitio web, especialmente durante ese período inicial crucial.
Sin embargo, este no es un problema irresoluble y tienes opciones:
- Usa las funciones de la plataforma web estándares disponibles en general en lugar de implementaciones redundantes basadas en JavaScript.
- Usa la herramienta de cobertura en Chrome DevTools para encontrar código sin usar en tus secuencias de comandos. Si reduces el tamaño de los recursos necesarios durante el inicio, puedes asegurarte de que las páginas dediquen menos tiempo a analizar y compilar código, lo que proporciona una experiencia del usuario inicial más fluida.
- Usa la división de código para crear un paquete independiente para el código que no es necesario para la renderización inicial, pero que se usará más adelante.
- Si utilizas un administrador de etiquetas, optimiza tus etiquetas periódicamente. Se pueden quitar las etiquetas más antiguas con código sin usar para reducir el espacio en JavaScript de tu administrador de etiquetas.
3. Evita las actualizaciones de renderización grandes
La ejecución de JavaScript es solo un factor que afecta la capacidad de respuesta de tu sitio web. La renderización es un tipo de trabajo costoso en sí mismo y, durante las actualizaciones de renderización grandes, es posible que tu sitio web responda aún más lento a las interacciones de los usuarios.
La optimización del trabajo de renderización no es un proceso sencillo y depende de lo que intentes lograr. Aun así, estas son algunas medidas que puedes tomar para asegurarte de que las tareas de renderización no se conviertan en tareas largas:
- Reorganiza las operaciones de lectura y escritura del DOM en tu código JavaScript para evitar el diseño forzado y la fragmentación del diseño.
- Mantén los tamaños de DOM pequeños. El tamaño del DOM y la intensidad del trabajo de diseño están correlacionados. Cuando el renderizador tiene que actualizar el diseño de un DOM muy grande, el trabajo necesario para volver a calcular su diseño puede aumentar significativamente.
- Usa la contención de CSS para renderizar de forma diferida el contenido del DOM fuera de la pantalla. No siempre es sencillo, pero si aislas las áreas que contienen diseños complejos, puedes evitar el trabajo de diseño y renderización innecesario.
Largest Contentful Paint (LCP)
El Largest Contentful Paint (LCP) es la métrica web esencial con la que los desarrolladores suelen tener más problemas: el 40% de los sitios del Informe sobre la experiencia del usuario en Chrome no cumple con el umbral de LCP recomendado para brindar una buena experiencia del usuario. El equipo de Chrome recomienda las siguientes técnicas como las formas más eficaces de mejorar el LCP.
1. Asegúrate de que el recurso de LCP sea detectable desde la fuente HTML y tenga prioridad
El equipo de Chrome observó lo siguiente en relación con el LCP en la Web:
- Según el Web Almanac 2024 de HTTP Archive, el 73% de las páginas para dispositivos móviles tiene una imagen como elemento de LCP.
- Un análisis de los datos de usuarios reales de Chrome muestra que la mayoría de los orígenes con un LCP deficiente dedican menos del 10% de su tiempo de LCP del p75 a descargar la imagen del LCP.
- Entre las páginas con un LCP bajo, la carga de sus imágenes de LCP se retrasa en el cliente en 1,290 milisegundos en el percentil 75, lo que representa más de la mitad del presupuesto para una experiencia rápida.
- De las páginas en las que el elemento LCP era una imagen, el 35% de esas imágenes tenía URLs de origen que no se podían detectar en la respuesta HTML inicial (como
<img src="...">
o<link rel="preload" href="...">
), lo que permitiría que el escáner de carga previa del navegador las detectara lo antes posible. - Según el Almanaque Web, el 15% de las páginas aptas aprovechaban el atributo HTML
fetchpriority
para dar prioridad a los recursos, incluidos aquellos que podrían mejorar la LCP de una página con relativamente poco esfuerzo.
Estas estadísticas son reveladoras, ya que los desarrolladores tienen una gran oportunidad para reducir el retraso en la carga de recursos y la duración de la carga de recursos para las imágenes de LCP.
Cuando el problema es la demora en la carga de recursos, es fundamental recordar que puede ser demasiado tarde para lograr un buen LCP si una página debe esperar a que CSS o JavaScript se carguen por completo antes de que las imágenes puedan comenzar a cargarse. Además, se puede reducir la duración de carga de recursos de una imagen de LCP si se vuelve a priorizar para que reciba más ancho de banda y, por lo tanto, se cargue más rápido con el atributo HTML fetchpriority
.
Si tu elemento LCP es una imagen, la URL de la imagen debe ser detectable en la respuesta HTML para reducir la demora en la carga de recursos. Estas son algunas sugerencias para lograrlo:
- Carga la imagen con un elemento
<img>
con el atributosrc
osrcset
. No uses atributos no estándar, comodata-src
, que requieran JavaScript para renderizarse, ya que siempre serán más lentos. El 7% de las páginas ocultan su imagen de LCP detrás dedata-src
. - Prefiere la renderización del servidor (SSR) en lugar de la renderización del cliente (CSR), ya que la SSR implica que el marcado completo de la página (incluida la imagen) está presente en la fuente HTML. Las soluciones de CSR requieren que se ejecute JavaScript para que se pueda descubrir la imagen.
- Si se debe hacer referencia a tu imagen desde un archivo CSS o JS externo, puedes incluirla en la fuente HTML con una etiqueta
<link rel="preload">
. Ten en cuenta que el escáner de carga previa del navegador no puede detectar las imágenes a las que se hace referencia con los estilos intercalados, por lo que, aunque se encuentren en la fuente HTML, es posible que el descubrimiento de estas imágenes siga bloqueado durante la carga de otros recursos, por lo que la carga previa puede ser útil en estos casos.
Además, puedes acortar la duración de carga de un recurso asegurándote de que el recurso de LCP se cargue con anticipación y con prioridad alta:
- Agrega el atributo
fetchpriority="high"
a la etiqueta<img>
o<link rel="preload">
de tu imagen de LCP. Esto aumenta la prioridad del recurso de imagen para que pueda comenzar a cargarse antes. - Quita el atributo
loading="lazy"
de la etiqueta<img>
de tu imagen de LCP. Esto evita la demora de carga causada por confirmar que la imagen aparece en el viewport o cerca de él. - Aplaza los recursos no esenciales siempre que sea posible. Mover estos recursos al final del documento, cargar imágenes de carga diferida o iframes, o cargarlos de forma asíncrona con JavaScript ayudará a despejar el camino para que los recursos más importantes, como la imagen de la LCP, se carguen más rápido.
2. Intenta lograr navegaciones instantáneas
La experiencia del usuario ideal es no tener que esperar a que se cargue una página. Las optimizaciones de LCP, como la visibilidad y priorización de recursos, son eficaces para reducir el tiempo que un usuario espera a que se cargue y renderice el elemento LCP, pero existe un límite físico para la rapidez con la que esos bytes se cargan a través de la red y se renderizan en una página. Mucho antes de alcanzar ese límite, se requiere un esfuerzo prohibitivo para reducir solo unos pocos milisegundos más. Por lo tanto, para lograr navegaciones instantáneas, debemos adoptar un enfoque radicalmente diferente.
Las navegaciones instantáneas intentan cargar y renderizar la página antes de que el usuario comience a navegar por ella. De esta manera, la página renderizada previamente se puede mostrar de inmediato con un LCP casi nulo. Las restauraciones y las especulaciones son dos maneras de hacerlo. Cuando un usuario navega hacia atrás o hacia adelante a una página que visitó anteriormente, se puede restablecer rápidamente desde una memoria caché en la memoria, y aparece exactamente como la dejó el usuario. Como alternativa, las aplicaciones web pueden intentar predecir adónde irá un usuario a continuación y, si la predicción es correcta, la siguiente página ya se habrá cargado y renderizado cuando el usuario navegue allí.
La memoria caché atrás/adelante (bfcache) permite restablecer las páginas visitadas anteriormente. Para usarla, debes asegurarte de que tus páginas cumplan con los criterios de elegibilidad de bfcache. Los motivos habituales por los que las páginas no son aptas para la bfcache son que se publican con directivas de almacenamiento en caché de no-store
o tienen objetos de escucha de eventos unload
.
La restauración de páginas renderizadas por completo mejora no solo el rendimiento de carga, sino también la estabilidad del diseño. Puedes obtener más información sobre bfcache y su eficacia para mejorar el CLS en la sección Cómo garantizar que las páginas sean aptas para bfcache.
Browser Support
La renderización previa de la siguiente página que visita un usuario es otra forma eficaz de mejorar de forma significativa el rendimiento del LCP, y es posible gracias a la API de Speculation Rules. Sin embargo, para obtener estos beneficios, asegúrate de que se rendericen previamente las páginas correctas. Las especulaciones incorrectas desperdician recursos en el servidor y en el cliente, lo que podría perjudicar el rendimiento. Por lo tanto, cuanto menos seguro estés de cuál será la siguiente página, más conservador debes ser con la renderización previa. Cuando tengas dudas, tus datos de estadísticas pueden darte la confianza para renderizar previamente las páginas con mayor probabilidad de que se visiten a continuación.
3. Usa una CDN para optimizar el TTFB
La recomendación anterior se enfocó en las navegaciones instantáneas, que proporcionan la mejor experiencia posible a los usuarios, pero podría haber situaciones en las que no se apliquen las técnicas de bfcache y carga especulativa. Considera un usuario que sigue un vínculo entre orígenes a tu sitio en el que la respuesta inicial del documento HTML bloquea de manera eficaz el LCP. El navegador no puede comenzar a cargar ningún subrecurso hasta que recibe el primer byte de la respuesta. Cuanto antes suceda, antes podrá comenzar a suceder todo lo demás.
Este tiempo se conoce como tiempo hasta el primer byte (TTFB). Las mejores formas de reducir el TTFB son las siguientes:
- Publica tu contenido lo más cerca posible de tus usuarios geográficamente.
- Almacena ese contenido en caché para que se pueda entregar rápidamente si se vuelve a solicitar en un futuro cercano.
La mejor manera de hacer ambas cosas es usar una CDN. Las CDN distribuyen tus recursos a servidores perimetrales en todo el mundo, lo que limita la distancia que esos recursos deben recorrer por cable hasta los usuarios. Por lo general, las CDN también tienen controles de almacenamiento en caché detallados que se pueden ajustar según las necesidades de tu sitio.
Las CDN también pueden entregar y almacenar en caché documentos HTML, pero según el Web Almanac, solo el 33% de las solicitudes de documentos HTML se entregaron desde una CDN. Esto significa que los sitios tienen una oportunidad significativa para obtener ahorros adicionales.
Estas son algunas sugerencias para configurar CDN:
- Almacena en caché documentos HTML estáticos, incluso por un período breve. Por ejemplo, ¿es importante que el contenido siempre esté actualizado? ¿O puede estar desactualizada unos minutos?
- Explora si puedes mover la lógica dinámica que se ejecuta en tu servidor de origen al periférico, que es una función de la mayoría de las CDN modernas.
Cada vez que puedes entregar contenido directamente desde el perímetro y evitar un viaje a tu servidor de origen, se obtiene un aumento de rendimiento. Incluso en los casos en los que debes realizar todo el recorrido hasta el origen, las CDN suelen estar optimizadas para hacerlo más rápido, por lo que es una ventaja de cualquier manera.
Cumulative Layout Shift (CLS)
El Cambio de diseño acumulado (CLS) es una medida de la estabilidad visual de una página web. Si bien la CLS es la métrica en la que la mayoría de los sitios suelen tener un buen rendimiento, alrededor de un cuarto de ellos aún no cumple con el umbral recomendado, por lo que muchos sitios tienen una gran oportunidad para mejorar la experiencia del usuario.
1. Establece tamaños explícitos en cualquier contenido cargado desde la página
Los cambios de diseño suelen ocurrir cuando el contenido existente se mueve después de que se termina de cargar otro contenido. La forma principal de mejorar el CLS es reservar el espacio necesario con anticipación tanto como sea posible.
La mejor manera de corregir los cambios de diseño causados por imágenes sin tamaño es configurar explícitamente los atributos width
y height
o sus propiedades CSS equivalentes. El 66% de las páginas tiene al menos una imagen sin tamaño. Sin un tamaño explícito, estas imágenes tienen una altura inicial de 0px
, lo que puede provocar cambios de diseño cuando se cargan estas imágenes y el navegador descubre sus dimensiones. Esto representa una gran oportunidad para la Web colectiva, y esa oportunidad requiere menos esfuerzo que algunas de las otras recomendaciones que se sugieren en esta guía.
Las imágenes no son los únicos factores que contribuyen a la CLS. Los cambios de diseño pueden deberse a otro contenido que, por lo general, se carga después de que se renderiza la página inicialmente, incluidos los anuncios de terceros o los videos incorporados. La propiedad aspect-ratio
puede ayudarte en este caso. Es una función de CSS estándar ampliamente disponible que permite a los desarrolladores establecer explícitamente una relación de aspecto en imágenes y elementos que no son de imagen. Esto te permite establecer un width
dinámico (por ejemplo, en función del tamaño de la pantalla) y hacer que el navegador calcule automáticamente la altura adecuada, de la misma manera que lo hace para las imágenes con dimensiones.
Sin embargo, no siempre es posible conocer el tamaño exacto del contenido dinámico. Incluso si no conoces el tamaño exacto, puedes reducir la gravedad de los cambios de diseño. Configurar un min-height
razonable casi siempre es mejor que permitir que el navegador use la altura predeterminada de 0px
para un elemento vacío. El uso de un min-height
también suele ser una solución directa, ya que permite que el contenedor crezca hasta la altura del contenido final si es necesario, solo que reduce esa cantidad de crecimiento a un nivel más tolerable.
2. Asegúrate de que las páginas sean aptas para el almacenamiento en la memoria caché atrás/adelante
Como se indicó anteriormente en esta guía, la memoria caché atrás/adelante (bfcache) carga instantáneamente una página anterior o posterior del historial del navegador a partir de una instantánea de memoria. Si bien la bfcache es una optimización significativa del rendimiento a nivel del navegador que mejora el LCP, también elimina por completo los cambios de diseño. De hecho, la introducción de bfcache en 2022 fue responsable de la mayor mejora en el CLS que vimos ese año.
A pesar de esto, una cantidad significativa de sitios web no son aptos para la bfcache y, por lo tanto, se están perdiendo este beneficio gratuito de rendimiento web. A menos que tu página cargue información sensible que no quieras que se restablezca desde la memoria, asegúrate de que tus páginas sean aptas para usar la bfcache.
Los propietarios de sitios deben verificar si las páginas son aptas para la bfcache y corregir los motivos por los que no lo son. Chrome tiene un verificador de bfcache en DevTools y también puedes usar la API de Not Restored Reasons para detectar los motivos de inelegibilidad en el campo.
3. Evita las animaciones y transiciones que usan propiedades CSS que inducen el diseño
Otra fuente común de cambios de diseño es cuando se animan los elementos. Por ejemplo, los banners de cookies y otros banners de notificaciones que se deslizan desde la parte superior o inferior suelen contribuir a la CLS. Esto es particularmente problemático cuando estos banners desplazan a otro contenido, pero incluso cuando no lo hacen, animarlos puede afectar el CLS.
Si bien los datos de HTTP Archive no pueden conectar de forma concluyente las animaciones a los cambios de diseño, los datos sí muestran que las páginas que animan cualquier propiedad CSS que pueda afectar el diseño tienen un 15% menos de probabilidades de tener un CLS "bueno" que las páginas en general. Algunas propiedades tienen un CLS peor que otras. Por ejemplo, las páginas que animan anchos de margin
o border
tienen un CLS "deficiente" con casi el doble de la frecuencia con la que las páginas en general se evalúan como deficientes.
Esto quizás no sea sorprendente, ya que cada vez que realices una transición o animes cualquier propiedad CSS que induzca un diseño, se producirán cambios de diseño. Si esos cambios de diseño no se producen dentro de los 500 milisegundos posteriores a una interacción del usuario, afectarán a la CLS.
Lo que puede sorprender a algunos desarrolladores es que esto es cierto incluso en los casos en que el elemento se toma fuera del flujo normal del documento. Por ejemplo, los elementos con posición absoluta que animan top
o left
causan cambios de diseño, incluso si no están desplazando otro contenido. Sin embargo, si, en lugar de animar top
o left
, animas transform:translateX()
o transform:translateY()
, el navegador no actualizará el diseño de la página, lo que evitará los cambios de diseño.
Preferir la animación de propiedades CSS que se pueden actualizar en el subproceso del compositor del navegador ha sido durante mucho tiempo una práctica recomendada de rendimiento porque traslada ese trabajo del subproceso principal a la GPU. Además de ser una práctica recomendada de rendimiento general, también puede ayudar a mejorar el CLS.
Como regla general, nunca animes ni realices transiciones de propiedades CSS que requieran que el navegador actualice el diseño de la página, a menos que lo hagas en respuesta a un toque del usuario o a una pulsación de tecla (aunque no hover
). Siempre que sea posible, prefiere las transiciones y animaciones con la propiedad transform
de CSS.
La auditoría de Lighthouse Evita las animaciones no compuestas advierte cuando una página anima propiedades CSS potencialmente lentas.
Conclusión
Mejorar el rendimiento de la página puede parecer abrumador, en especial, porque hay una gran cantidad de orientación en la Web que debes tener en cuenta. Sin embargo, si te enfocas en esta breve lista de las prácticas recomendadas más eficaces, puedes abordar el problema con un enfoque renovado y, con suerte, mejorar las Métricas web esenciales de tu sitio web.
Si quieres ir más allá de las optimizaciones que se enumeran aquí, lee estas guías para obtener más información:
Apéndice: Registro de cambios
Aquí se hará un seguimiento de los cambios importantes en este documento para ayudar a explicar cuándo y por qué cambiaron las recomendaciones principales.
Octubre de 2024
Actualización de 2024:
- INP
- Cambiamos esta métrica de FID a INP de acuerdo con el lanzamiento de INP como métrica de Métricas web esenciales y la convertimos en la métrica principal de la lista.
- Revirtieron nuestra recomendación de usar la API de
isInputPending
como parte de la división de tareas largas. Puedes obtener más información sobre nuestro razonamiento en el artículo Cómo optimizar tareas largas.
- LCP
- Combinamos las recomendaciones de visibilidad y priorización en una sola.
- Agregamos una nueva recomendación para apuntar a navegaciones instantáneas.
Enero de 2023
Esta es la lista inicial de recomendaciones:
- LCP
- Asegúrate de que el recurso de LCP sea detectable desde la fuente HTML
- Asegúrate de que el recurso de LCP tenga prioridad
- Usa una CDN para optimizar el TTFB de documentos y recursos
- CLS
- Establece tamaños explícitos en cualquier contenido cargado desde la página
- Asegúrate de que las páginas sean aptas para el almacenamiento en la memoria caché atrás/adelante
- Evita las animaciones y transiciones que usan propiedades CSS que inducen el diseño
- FID
- Evita o divide las tareas largas
- Evita el código JavaScript innecesario
- Evita las actualizaciones de renderización grandes
También puedes mirar esta presentación de Google I/O 2023 para ver un resumen en video.