Optimizar imágenes para Core Web Vitals

Aprende cómo las imágenes afectan los Core Web Vitals y cómo optimizarlas

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2024-11-27

¿Cómo pueden las imágenes afectar los Core Web Vitals?

Las imágenes juegan un papel importante en mejorar el atractivo visual de un sitio web, pero también pueden tener un impacto significativo en su velocidad de carga. Los Core Web Vitals son un conjunto de métricas que Google utiliza para medir la user experience de un sitio web, y la optimización de imágenes es un factor crítico para lograr buenas puntuaciones. En este artículo, discutiremos cómo optimizar imágenes para Core Web Vitals y mejorar la velocidad de carga de tu sitio web.

Comprender los Core Web Vitals

Antes de profundizar en la optimización de imágenes, revisemos brevemente los Core Web Vitals. Son un conjunto de métricas centradas en el usuario que miden la velocidad de carga, la interactividad y la estabilidad visual de una página web. Las tres métricas clave son:

Largest Contentful Paint (LCP): mide la velocidad de carga del elemento más grande de la página.
First Input Delay (FID): mide el tiempo que tarda la página en volverse interactiva.
Cumulative Layout Shift (CLS): mide la estabilidad visual de la página.

¿Qué Core Web Vitals pueden verse afectados por las imágenes?

Puede que te sorprenda saber que las imágenes pueden afectar todos los Core Web Vitals. Las imágenes, si se ponen en cola para descarga en un momento tardío durante el renderizado o si simplemente son demasiado grandes, generalmente resultarán en una puntuación LCP alta. Si las dimensiones de la imagen no están definidas o cambian durante la fase de carga, las imágenes también pueden afectar la puntuación CLS. Y finalmente, si la decodificación de imágenes consume demasiado trabajo del hilo principal, incluso pueden afectar el INP. Veamos más de cerca:

Largest Contentful Paint

Uno de los Core Web Vitals es Largest Contentful Paint (LCP), que mide cuánto tiempo tarda el elemento más grande de la página (como una imagen o un vídeo) en hacerse visible para el usuario. Si una imagen se encola demasiado tarde o tarda demasiado en cargarse, puede ralentizar significativamente la puntuación LCP de la página.

Cumulative Layout Shift

Otro Core Web Vital es Cumulative Layout Shift (CLS), que mide cuánto se desplaza el contenido de una página mientras se carga. Las imágenes pueden causar desplazamientos de diseño si no están dimensionadas correctamente o si se insertan en la página después de que ya se haya cargado, causando que otros elementos se muevan.

First Input Delay e INP

Finalmente, las imágenes también pueden impactar el tercer Core Web Vital, el INP, que mide el tiempo que tarda una página en responder visualmente después de que el usuario interactúa con ella. Si hay demasiadas imágenes grandes que necesitan ser decodificadas, la página puede tardar más en responder a las interacciones del usuario, resultando en una puntuación INP deficiente.

Paso 1: Optimizar el elemento de imagen HTML para velocidad

Lo primero que debes verificar al optimizar imágenes es el código HTML de todas las imágenes. Las imágenes son simples y los navegadores son excelentes haciendo tareas simples. Así que intenta evitar trucos y soluciones ingeniosas y simplemente usa la etiqueta de imagen html clásica <img> ¡y usa todas las opciones que tienes para acelerar tus imágenes!

Atributo Src

Especifica la URL de la imagen. Esta propiedad es esencial, ya que le indica al navegador dónde encontrar la imagen.

Atributos Width y height

Especifica el ancho y alto de la imagen en píxeles. Estas propiedades son importantes para renderizar la imagen correctamente en la página, ya que definen el tamaño del contenedor de la imagen y cómo la imagen se ajusta dentro de él.

Atributo Alt

Especifica texto alternativo para la imagen si no se puede mostrar. Esto es importante para fines de accesibilidad, ya que ayuda a los usuarios con discapacidad visual a entender de qué trata la imagen. También es importante para SEO, ya que los motores de búsqueda usan el texto alt para entender el contenido de la imagen.

Atributo Loading (carga diferida)

Especifica cómo el navegador debe cargar la imagen (lazy, eager o auto). Esta propiedad es importante para mejorar el rendimiento de la página, ya que permite que las imágenes se carguen de forma asíncrona y solo cuando se necesitan.

Atributo Srcset

Especifica una lista separada por comas de fuentes de imagen y sus tamaños, lo que permite al navegador elegir la mejor fuente de imagen basándose en el tamaño de pantalla y la resolución del dispositivo. Esta propiedad es importante para el diseño responsive, ya que asegura que los usuarios obtengan la mejor calidad de imagen posible independientemente de su dispositivo.

Atributo Sizes

Especifica los tamaños de la fuente de imagen a usar según el tamaño del viewport. Esta propiedad funciona en conjunto con srcset para asegurar que el tamaño correcto de imagen se cargue en diferentes dispositivos y tamaños de pantalla, mejorando el rendimiento general de la página.

Atributo Decoding

Especifica cómo el navegador debe decodificar la imagen (async, sync o auto). Esta propiedad también es importante para mejorar el rendimiento de la página, ya que permite al navegador (des)priorizar la decodificación de la imagen sobre el renderizado del resto de la página.

Atributo Fetchpriority

El atributo fetchpriority especifica la prioridad de la descarga de un recurso en relación con otros recursos de la página. El atributo de prioridad puede tener uno de tres valores: "high", "medium" o "low". Un recurso con prioridad alta se carga antes que los recursos con prioridades media o baja. Un recurso con prioridad media se carga antes que los recursos con prioridad baja. Los recursos con la misma prioridad se cargan en el orden en que aparecen en el HTML.

Paso 2: Asegurar que la imagen se encole para descarga lo antes posible

Lo segundo que debes hacer, después de haber optimizado el HTML, es revisar la programación de descarga de imágenes. En muchos casos, el mayor cuello de botella en cuanto a cómo las imágenes afectan la métrica LCP es la programación tardía. Si un navegador tiene la oportunidad de descargar el elemento LCP temprano durante el proceso de renderizado, la imagen estará disponible para el navegador lo antes posible y el navegador podrá comenzar a pintar ese elemento temprano en el proceso de renderizado.

¿Suena simple verdad? Bueno, ¿cómo nos aseguramos de que la imagen se encole para descarga lo antes posible?

Precargar el elemento LCP

La forma más efectiva de asegurar una descarga temprana es precargar la imagen. La precarga de la imagen se hace con una etiqueta simple al inicio del elemento <head>. Por ejemplo:

<link rel="preload" as="image" href="image.jpg">

Esta simple etiqueta le dirá al navegador que necesitaremos "image.jpg" muy pronto y el navegador comenzará a descargar este archivo inmediatamente.

Cargar eager el elemento LCP

Siempre debes evitar la carga diferida del elemento LCP. Si cargas de forma diferida el elemento LCP, la carga diferida basada en JavaScript es especialmente mala para la velocidad de página. La carga diferida basada en JavaScript depende de un script para reescribir tu etiqueta <img>. Normalmente el img tendrá un atributo data-src que es reescrito a un atributo src por JavaScript. El problema con esto es doble:
1. El escáner de precarga del navegador no reconoce el atributo data-src y no activará proactivamente el elemento para una descarga temprana.
2. La carga diferida basada en JS necesita esperar a que un JavaScript se cargue y ejecute. Esto generalmente ocurre relativamente tarde durante el proceso de renderizado. Esto causa un retraso aún mayor en la imagen.

Para evitar este problema por completo, asegúrate de que el elemento LCP siempre se cargue de forma eager. Como 'eager' es el valor por defecto para cualquier imagen, solo necesitas asegurarte de que la imagen no se cargue de forma diferida. Haz esto eliminando el atributo nativo 'loading="lazy"' o si estás usando un plugin de optimización, consulta la documentación sobre cómo omitir la carga diferida para una imagen.

Usar fetchpriority alto

Si, por alguna razón, no puedes precargar el elemento LCP, al menos asegúrate de que el elemento tenga el atributo fetchpriority establecido en high. Esto le indicará al navegador que la imagen es importante para la página y el navegador la descargará con alta prioridad. Ten en cuenta que usar fetchpriority="high" generalmente no es tan eficiente como precargar una imagen.

Evitar la carga diferida basada en JavaScript

Siempre debes evitar la carga diferida del elemento LCP. Si cargas de forma diferida el elemento LCP, la carga diferida basada en JavaScript es especialmente mala para la velocidad de página. La carga diferida basada en JavaScript depende de un script para reescribir tu etiqueta <img>. Normalmente el img tendrá un atributo data-src que es reescrito a un atributo src por JavaScript. El problema con esto es doble:
1. El escáner de precarga del navegador no reconoce el atributo data-src y no activará proactivamente el elemento para una descarga temprana.
2. La carga diferida basada en JS necesita esperar a que un JavaScript se cargue y ejecute. Esto generalmente ocurre relativamente tarde durante el proceso de renderizado. Esto causa un retraso aún mayor en la imagen.

Paso 3: Asegurar que la imagen se descargue lo más rápido posible

Lo tercero que debes hacer es asegurarte de no desperdiciar recursos de red valiosos en imágenes que son más grandes de lo que deberían ser. Puedes hacer esto usando imágenes responsive, usando compresión y usando contenedores de imagen nuevos y más rápidos.

Imágenes responsive

Uno de los problemas más comunes con el LCP es enviar una 'imagen hero' de escritorio a tamaño completo de 1920x1200px a un dispositivo móvil que renderiza la imagen a aproximadamente 360x225. Esto significa que la imagen es aproximadamente 28 veces más grande de lo que debería ser (claro, podrías enviar imágenes a un DPI más alto, ¡entonces la imagen a tamaño completo sería 7 veces más grande!)!
¡Ahí es donde entran las imágenes responsive! Las imágenes responsive envían una versión diferente de una imagen a diferentes viewports. Esto significa que podemos enviar una imagen pequeña a un navegador móvil, una imagen ligeramente más grande a una tablet y una imagen a tamaño completo a un escritorio para asegurarnos de que no se envíen bytes innecesarios.

Compresión de imágenes

La compresión de imágenes te permite reducir el tamaño de archivo de una imagen mientras se preserva la mayor parte de su calidad visual. Implica varias técnicas que eliminan datos redundantes o irrelevantes. La mayoría de los sistemas CMS modernos aplican compresión de imágenes cuando las imágenes se suben a la biblioteca. Sin embargo, si omites la biblioteca o usas tu propia solución personalizada, ¡siempre verifica que las imágenes tengan el nivel de compresión correcto!

Contenedores de imagen nuevos y más rápidos

Las imágenes a menudo son uno de los recursos más grandes en una página web, y pueden ralentizar significativamente la velocidad de carga de una página si no están optimizadas. Los contenedores de imagen más nuevos y rápidos, como los formatos WebP y AVIF, pueden ayudar a reducir el tamaño de archivo de las imágenes sin sacrificar su calidad. Esto significa que pueden cargarse más rápidamente, lo que puede mejorar la velocidad de carga de la página.

Paso 4: ¡Eliminar el Layout Shift!

Las imágenes que cambian de tamaño mientras se cargan causarán un layout shift. Es así de simple. Hay 3 razones principales por las que las imágenes causan un layout shift (en realidad hay muchas más, pero estas 3 son las más comunes)

1. Dimensiones de imagen faltantes

Las dimensiones de imagen son el atributo width y el atributo height de la imagen. Si el atributo width o height no está establecido, el navegador no sabe cuánto espacio reservar para la imagen durante el renderizado y reservará 0 píxeles para cualquier dimensión faltante.

Esto significa que una imagen sin width y height establecidos se renderizará a 0x0 píxeles y luego, cuando la imagen se haya cargado y decodificado, el navegador recalculará el diseño para usar la cantidad correcta de espacio para la imagen.

2. Problemas de estilos

Generalmente se evita que las imágenes crezcan más que el viewport con un simple truco CSS

img{
   max-width:100%;
height:auto; }

Este es un gran truco y deberías usarlo. Desafortunadamente, regularmente veo variantes de este truco que sí causan un layout shift. Por ejemplo, agregando width:auto:

img{
   max-width:100%;
height:auto; width:auto; }

Esto hará que cualquier imagen se renderice con un width y height automáticos. Esto generalmente significa que el navegador renderizará la imagen a 0x0px antes de que la imagen se haya descargado.

3. Placeholders

Algunos scripts de carga diferida basados en JavaScript usan placeholders. Si usas algún tipo de truco CSS como el mencionado max-width:100% y height:auto, entonces el autoheight del placeholder cuadrado no coincidirá con el atributo height de la imagen. Básicamente, la imagen primero se renderizará con el placeholder cuadrado a 720x720 y cuando la imagen final se haya descargado, se renderizará a 720*180

<img 
  src="1x1placeholder.png" 
  data-src="hero.png" 
  width="720" 
  height="180"
  style="height:auto;max-width:100%"
>


Paso 5: Proteger el hilo principal

Lo siguiente que debes asegurar es que no se decodifiquen demasiadas imágenes en el hilo principal al mismo tiempo. Generalmente esto no será un problema, pero lo he visto ocurrir muchas veces en páginas de listado de productos (¡donde a veces hasta 500 imágenes compiten por recursos!).

El truco es agregar decoding="async" a todas las imágenes para asegurar que estas imágenes puedan decodificarse en un hilo separado. También intenta evitar que tantas imágenes se decodifiquen a la vez agregando loading="lazy" a todas las imágenes debajo del pliegue y las imágenes ocultas.

Paso 6: ¡Elige la estrategia correcta para cada imagen!

El paso final, y a veces el más importante, es priorizar las imágenes importantes y des-priorizar las imágenes no importantes.

Estrategias de imagen para el elemento LCP

El elemento LCP generalmente es el elemento visual más importante. Así que realmente necesitamos priorizar este."

  1. Precarga la imagen temprano en el head de la página con este código: <link rel="preload" as="image" href="path-to-img.png">
  2. Indica al navegador que esta imagen no debe cargarse de forma diferida estableciendo loading="eager" u omitiendo el atributo loading
  3. Indica al navegador que esta imagen debe descargarse con alta prioridad usando fetchpriority="high" (si estás precargando la imagen, puedes omitir esta parte)
  4. Establece decoding="sync" ya que este elemento es tan importante que queremos decodificarlo en el hilo principal

Estrategia de imagen para logos y otras imágenes visibles (no LCP)

Las imágenes visibles deben cargarse bastante pronto durante la carga de la página, pero preferiblemente después del elemento LCP. Podemos lograr esto precargando el elemento LCP. Esto le dará a estas imágenes visibles su orden de descarga natural y correcto.

  1. Indica al navegador que esta imagen no debe cargarse de forma diferida estableciendo loading="eager" u omitiendo el atributo loading
  2. Establece decoding="async" ya que este elemento puede decodificarse de forma segura fuera del hilo principal.

Estrategia de imagen para imágenes debajo del pliegue

Todas las imágenes debajo del pliegue deben cargarse de forma diferida. ¡Es así de simple! ¡No hay excepciones!

  1. Indica al navegador que esta imagen debe cargarse de forma diferida estableciendo loading="lazy"
  2. Establece decoding="async" ya que este elemento puede decodificarse de forma segura fuera del hilo principal.

Evitar imágenes de fondo

Si estás usando imágenes de fondo, necesitas reconsiderar. Las imágenes de fondo no pueden cargarse de forma diferida y no puedes controlar la propiedad de decodificación ni establecer el fetchpriority. Las imágenes de fondo generalmente no son responsive, lo que probablemente te costará mucho ancho de banda. Pero lo más importante, las imágenes de fondo generalmente se descubren después de que el navegador ha descargado los archivos CSS. ¡Este casi nunca es el momento correcto para iniciar una descarga de imagen!

¡Puedes usar etiquetas de imagen normales en combinación con el CSS object-fit:cover para hacer que las imágenes normales se comporten como imágenes de fondo!

Urgent Fix Required?

Google Search Console failing? I offer rapid-response auditing to identify the failure point within 48 hours.

Request Urgent Audit >>

  • 48hr Turnaround
  • Rapid Response
  • Failure Identification
Optimizar imágenes para Core Web Vitals Core Web Vitals Optimizar imágenes para Core Web Vitals