Optimización de imágenes web

Hipólito Pérez García
planetahuerto
Published in
6 min readAug 28, 2020

Cuando tratamos de optimizar imágenes para nuestro sitio web, siempre nos rondan las mismas preguntas: ¿Cuál es el tamaño óptimo para nuestras imágenes? ¿Qué resolución debe tener la imagen para que no pierda calidad?¿Cuál es el formato correcto que debemos usar? En este artículo vamos a resolver todas estas dudas e ir un paso más allá, aplicando técnicas y procesos que ayuden a conseguir una web rápida y ligera a la hora de cargar imágenes.

Tamaño de imágenes

Es muy importante saber qué tamaño queremos que tengan nuestras imágenes, ya que es lo que determinará en mayor medida su peso y por lo tanto la carga de nuestra web. Cuanto menos tamaño tenga, menos pesará, pero no podemos elegir siempre un tamaño pequeño para que pese poco, tendremos que tener en cuenta que si se introduce en un contenedor de mayor tamaño la imagen se pixelará y perderá calidad. Por lo que siempre intentaremos ajustar el tamaño de nuestra imagen al tamaño del contenedor que contendrá esta imagen en la web.

Al duplicar el tamaño de la imagen observamos que aumenta de 32 a 93 kB.

Aunque no todo dependerá del tamaño del contenedor, nuestro dispositivo puede tener más píxeles en un contenedor que píxeles CSS, por lo que si queremos mostrar imágenes con mucho detalle, podremos cargar imágenes en un contenedor de menor tamaño que el de la imagen, siempre y cuando no supere el “device pixel ratio” del dispositivo.

Device Pixel Ratio

En Javascript la variable window.devicePixelRatio nos muestra el ratio de píxeles que tiene nuestro dispositivo. Este ratio hace referencia a la cantidad de píxeles del dispositivo por píxeles CSS. Para calcular los píxeles de nuestro dispositivo tendremos que multiplicar el ancho del contenedor por el device pixel ratio, por ejemplo, el nexus 5X tiene 412 CSS píxeles de ancho, con un device pixel ratio de 2.625, si multiplicamos, el resultado es de ~1080px de resolución de pantalla.

Google tendrá en cuenta el tamaño en píxeles de nuestra imagen según la resolución de pantalla.

Prueba lighthouse en Nexus 5X

A pesar de que la imagen web ocupe solo 36KB, nos dice que podríamos mejorarla porque es de 2100px en una resolución de 1080px, por lo que todas las imágenes que superen esta cantidad serán penalizadas por Google.

Responsive Images

Para que nuestras imágenes se ajusten a cada uno de nuestros dispositivos y tamaños de pantalla, podremos tener varios tamaños de la misma imagen y elegir cual se tiene cargar en cada caso. Para ello utilizaremos el elemento HTML <picture>. Tendremos que tener en cuenta que este elemento no es soportado por IE y versiones antiguas de navegadores.

La etiqueta picture y source nos permiten cargar diferentes imágenes según el ancho de nuestro dispositivo y su devicePixelRatio o cargar archivos como webp con alternativas en el caso de que este formato no sea soportado por el navegador.

<picture>
<source
media="(min-width: 800px)"
srcset="head.jpg, head-2x.jpg 2x"
>
<source
media="(min-width: 450px)"
srcset="head-small.jpg, head-small-2x.jpg 2x"
>
<img
src="head-fb.jpg"
srcset="head-fb-2x.jpg 2x"
alt="a head carved out of wood">
</picture>

El tag source nos permite establecer diferentes archivos opcionales. En el código anterior, a partir de 450px se cargará una serie de imágenes y a partir de 800px otras con mayor tamaño. Como observamos en el atributo :srcset indicamos 2 tipos de imágenes con tamaños diferentes separadas por comas, la primera se cargaría si tuviéramos un device pixel ratio de 1 y la segunda acompañada de un “2x” se cargaría si el dispositivo supera en 2 el ratio de píxeles (si window.devicePixelRatio > 2).

Lo normal es que carguemos las imágenes según el tamaño del dispositivo y del contenedor, pero si queremos que la imagen tenga mucho más detalle y sacar el máximo partido podríamos contemplar la posibilidad de cargar imágenes según el device pixel ratio. Aún así tendremos que tener en cuenta que las imágenes serán de mayor tamaño y pesarán más, por lo que aumentará el tiempo de carga de nuestra web. Dependerá de nosotros mismos tomar la decisión de cargar o no imágenes según su device pixel ratio.

Resolución de Imágenes.

Una de las dudas más frecuentes es saber qué resolución tendrá que tener nuestra imagen para que se vea bien en todos los dispositivos. Os adelanto la respuesta; da igual. La resolución no afecta a la impresión por pantalla, está ligada a la impresión por papel. Con exportar nuestras imágenes con 72dpi es suficiente para que se muestre correctamente en nuestras pantallas.

Formato de imágenes

Existen diferentes métodos de compresión que se usan en los formatos de archivo: GIF, JPEG, PNG, TIFF, etc. El peso de los archivos en cada uno de los formatos pueden ser muy distintos aún teniendo las mismas dimensiones en píxeles, de igual manera, la profundidad de los bits de color, la cantidad de capas y los diferentes canales de una imagen afectan al peso del archivo.

Existe otro formato de archivo a los mencionados anteriormente que cabe resaltar, es el llamado webP. Este formato está optimizado para la lectura de imágenes en web, por lo que te proporcionará una buena calidad de imagen con un peso menor que el de otros formatos siendo del mismo tamaño. Pero cuidado, actualmente webP no está soportado por todos los navegadores, por lo tanto tendremos que tenerlo en cuenta a la hora de cargar nuestras imágenes.

Como hemos comentado con el elemento picture podríamos aplicar el formato webP y mostrar formatos alternativos para los navegadores que no lo soporten.

<picture>
<source srcset="/img/img_big.webp" type="image/webp">
<img src="/img/img_big.jpg" alt="big picture">
</picture

Para elegir el formato correcto de nuestras imágenes tenemos que tener en cuenta:

  • Utiliza PNG para mantener el fondo transparente y querer mostrar una calidad de colores superior a JPEG.
  • Usa WebP y no JPEG o PNG. Debes tener en cuenta que afectará a la visualización en los navegadores no compatibles.
  • Evita utilizar formatos GIF animados ya que suelen pesar mucho.

Si no puedes dar soporte a WebP y no necesitas tener el fondo transparente el formato estándar para las imágenes es JPEG (JPG).

Lazy load de imágenes

El término “lazy load” es la estrategia de carga de contenido solo cuando es requerido por el cliente. Con este método conseguiremos que nuestro sitio cargue más rápido, haciendo que ciertos contenidos se procesen durante la navegación del usuario y no en una primera carga inicial.

Para aplicar esta estrategia a nuestra web es necesario recurrir a librerías JS. Aunque podamos tener nativamente un “lazy load” con el atributo loading, a día que escribimos este artículo no todos los navegadores soportan esta característica, por lo que podemos hacer un mix entre el nativo y librerías JS dependiendo si el navegador es compatible, o directamente utilizar una librería.

La técnica más usada para el lazy load de imágenes es cargar el contenido de la imagen en el elemento <img> en un atributo diferente al :src, por ejemplo en el atributo :data-src. Una vez el contenido se requiere, trasladaremos el valor de :data-src a :src para cargar la imagen.

<img data-src="image.jpg" src="" alt="test image" />
Simple lazy-load con Nuxt e IntersectionObserver

Gestión de imágenes en la nube

Algunas plataformas permiten gestionar todos tus ficheros en la nube, proporcionando herramientas para almacenar, optimizar, modificar y proveer tus imágenes de una forma casi automática.

Algunas de las ventajas más relevantes de este tipo de plataformas es poder optimizar el peso, cambiar los formatos y modificar el tamaño y el contenido de la imagen en la nube mediante una API. Podemos cambiar el formato de una imagen de JPG a webP según si el navegador soporta este tipo de imágenes, modificar el tamaño de la imagen según el dispositivo en el que nos encontremos, y muchas otras acciones sin la necesidad de previamente haber tenido que generar nosotros mismos todos los ficheros con los diferentes formatos y tamaños. A partir de una sola imagen se generarán todos los tipos de imágenes que deseemos a demanda.

Por supuesto estos servicios suelen contar con un sistema de caché para que la imagen no tenga que ser procesada en cada petición que hagamos.

En el siguiente enlace podréis encontrar una herramienta muy útil que nos permite generar varios tamaños de imágenes de una sola imagen.
Responsive images

Lazy load de imágenes con picture en Nuxt

Para cerrar este artículo, qué mejor forma que dejaros un ejemplo de cómo cargar imágenes con todo lo aprendido en este artículo.

--

--