Cómo optimizar la carga de imágenes en su sitio web

Un sitio web lleno de imágenes puede ser un gran cuello de botella para el rendimiento del sitio web. Así es como optimicé la carga de imágenes para lograr una mejor experiencia de usuario.

Tener un sitio web lleno de bellas imágenes es excelente y puede ser un gran cuello de botella para la carga de la página. A menudo veo sitios web que cargan imágenes de varios megabytes solo para tener un control deslizante en su página de inicio. Imagínese en una conexión celular 3G lenta cargando ese sitio web. Eso tomaría años en cargarse y los usuarios dejarían su sitio web. Una buena forma de probar esto en su sitio web actual es seleccionando la limitación de red en Chrome Devtools.

Problema

El problema aquí es que a menudo el documento del sitio ya está cargado mientras las imágenes aún se están cargando. Esto da como resultado secciones vacías en su página donde se carga lentamente una imagen. No es lo que desea.

En el siguiente ejemplo, creé un sitio web simple que contiene una imagen de fondo de 4.8MB. Como puede ver, el DOM se carga en 1.14 segundos. Entonces, básicamente, el usuario ve el contenido después de 1.14 segundos. Bastante bueno para una red 3G. Sin embargo, la imagen de fondo tarda 27,32 segundos en cargarse cuando el usuario ve que se están cargando partes de las imágenes. Es posible que el usuario ya haya abandonado su sitio web en este momento.

Un sitio web simple mal optimizado con una imagen de fondo de 4.8MB en una red celular 3G rápida

Parece que no solo su experiencia de usuario está disminuyendo debido a esto. En 2010, Google declaró que la velocidad de la página es un factor en su algoritmo de clasificación. Mi expectativa es que esto se haya convertido en un factor cada vez más importante a lo largo de los años. Google parece invertir mucho en informar a los desarrolladores sobre el rendimiento de la página en sus conferencias.

Solución

Entonces, ¿cómo superamos este problema? Bueno, lo primero que podemos hacer es comprimir la imagen de fondo utilizando varias herramientas en Internet. Esta es una victoria fácil y reducirá el tiempo de carga a unos diez segundos. Esto parece un gran paso, pero diez segundos sigue siendo demasiado.

El siguiente paso sería cargar una llamada imagen de "marcador de posición" antes de cargar realmente la imagen original. Este "marcador de posición" es una variante de baja resolución de la imagen original. Cuando creamos esta imagen, hemos reducido la resolución de la imagen de 7372x4392 píxeles a 20x11 píxeles. Esto da como resultado un tamaño de imagen de 4.8MB a 900 bytes.

Esta reducción en el tamaño da como resultado un tiempo de carga de 550 milisegundos en lugar de los 10 segundos. Pero ahora tenemos una imagen borrosa de baja resolución como fondo. Esto es perfecto para los primeros segundos que se carga la página, pero queremos brindarle al usuario la gran experiencia de nuestra imagen de fondo original.

Para hacerlo, primero queremos cargar la imagen de baja resolución y cargar ya la imagen de alta resolución de forma asíncrona en segundo plano. Una vez que se carga la imagen de alta resolución, queremos cambiar la baja resolución con la imagen de alta resolución.

Para lograr esto, utilicé el siguiente javascript que cargué antes de la etiqueta del cuerpo final. De esta manera, nuestro script no bloquea el contenido de nuestra página.

(() => {
  'uso estricto';
  // La página está cargada
  objetos const = document.getElementsByClassName ('asyncImage');
  Array.from (objetos) .map ((elemento) => {
    // Comienza a cargar la imagen
    const img = nueva imagen ();
    img.src = item.dataset.src;
    // Una vez que se carga la imagen, reemplace el src del elemento HTML
    img.onload = () => {
      item.classList.remove ('asyncImage');
      return item.nodeName === 'IMG'?
        item.src = item.dataset.src:
        item.style.backgroundImage = `url ($ {item.dataset.src})`;
    };
  });
}) ();

La función javascript escanea el DOM en busca de cualquier clase "asyncImage". Después de eso, cargará todas las imágenes que se proporcionan en el atributo data-src en estos elementos. Una vez que se carga una imagen, reemplazará la fuente de la etiqueta de imagen o la imagen de fondo de un elemento IMG.

...

o

Hermoso paisaje del amanecer

Debido a que el script elimina la clase del elemento una vez que se ha cambiado la imagen, podemos hacer algunas transiciones CSS increíbles si lo deseamos. Por ejemplo, una transición de entrada y salida que provocará un desvanecimiento una vez que se reemplace la imagen.

Conclusión

entonces, ¿qué hicimos? Mejoramos nuestra experiencia de usuario, hicimos que nuestro sitio web se cargara más rápido, lo hicimos más accesible para los usuarios sin una conexión rápida y posiblemente mejoramos nuestro ranking en Google. Esa es una gran mejora para un cambio tan pequeño.

La nueva situación en la que primero cargamos una imagen de baja resolución y luego la reemplazamos con la imagen original

Como puede ver, cargamos una imagen de marcador de posición en 570ms. Una vez que se carga, el usuario ve la versión borrosa de baja resolución de la imagen original. Una vez que se carga la imagen original, reemplazará la imagen de baja resolución.

Ya no tenemos problemas extraños de representación de imágenes y le damos al usuario una primera pintura rápida.

Vea un ejemplo de trabajo aquí

Imágenes de carga diferida

Cuando desee mejorar aún más su proceso de carga de imágenes, puede considerar cargar lentamente sus imágenes.

La carga diferida es una técnica en la que las imágenes que no se dirigen directamente a la ventana gráfica de un usuario no se cargan. Una vez que la imagen se acerca al borde de la ventana gráfica, se carga la imagen.

El beneficio de esto es menos bytes para cargar en la carga inicial de la página. A menudo no es necesario mostrar todas las imágenes en la ventana gráfica del usuario. Una vez que el usuario comienza a desplazarse, necesitamos más y más contenido que se pueda cargar. Un buen enfoque para implementar este comportamiento es echar un vistazo al Intersection Observer.

Espero que hayas disfrutado leyendo este artículo y estés emocionado de implementar esta mejora tú mismo :). Algunos aplausos significarían mucho.