Google Lab: Responsive Images

Hay dos aspectos fundamentales a considerar cuando se trabaja con imágenes en web: rendimiento y adaptabilidad.

Objetivo del lab: aumentar el rendimiento reduciendo el coste de descarga.

Sumario
  1. Establecer ancho relativo
  2. Usando el atributo srcset
  3. Usando el atributo sizes
  4. Usando media queries
  5. Opcional: usando los elementos picture y source
  6. Otros formatos de imagen: svg y webp
  7. Rendimiento (Firefox y Chrome)
  8. rendimiento CSS min vs CSS

1. Establecer ancho relativo

Antes de hacer las imágenes adaptativas hay que asegurar que no desborden la pantalla.

img { max-width: 100%; } /* El valor de max-width representa un porcentaje del elemento contenedor.*/
happy music bird
Fuente: unDraw

Nota: El max-width se puede especificar en función del ancho del viewport utilizando las unidades vw (por ejemplo, 100vw).

Propiedad/valor
max-width
4.0
12.0
2.0
10.0
3.1
%
1.0
3.0
1.0
3.5
1.0
vw
26.0
16.0
19.0
20.0
6.1

Primera versión del navegador que soporta totalmente la propiedad o el valor. Fuente: Can I Use


2. Usando el atributo srcset

El objetivo es conseguir que el navegador obtenga la versión de la imagen con las dimensiones más pequeñas posibles, pero mayor que el tamaño de visualización final de la imagen. srcset permite listar un conjunto de imágenes con diferentes resoluciones para que el navegador elija al obtener la imagen. La elección del navegador depende de las dimensiones del viewport, el tamaño de la imagen en relación con el viewport, la densidad de píxeles del dispositivo del usuario y las dimensiones del archivo fuente.

<img srcset="img/undraw_happy_music-1600_large.png 1600w, img/undraw_happy_music-1000_large.png 1000w, img/undraw_happy_music-800_medium.png 800w, img/undraw_happy_music-500_small.png 500w" src="img/undraw_happy_music-1600_large.png" alt="happy music bird" >
happy music bird
Fuente: unDraw

Importante: para la carga adecuada del tamaño de la imagen en función de la anchura viewport hay que indicarle al navegador el tamaño de cada archivo antes de que lo recupere (por ejemplo, 1600w).

Añadir un descriptor de anchura a cada archivo en el srcset, indica al navegador la anchura de cada imagen en píxeles antes de que la obtenga. El navegador puede entonces utilizar estas anchuras para decidir qué imagen obtener en función del tamaño de su ventana. Obtiene la imagen con la anchura más pequeña que aún es mayor que la anchura del viewport. Si srcset no está soportado cargará por defecto la imagen de src.

Nota: Se puede especificar la densidad de pixels en lugar de la anchura. (Ver punto 5)

Atributo
srcset
38.0
16.0
38.0
25.0
9.0

Primera versión del navegador que soporta totalmente el atributo. Fuente: Can I Use


3. Usando el atributo sizes

HTML

<img id="bird" srcset="img/undraw_happy_music-1600_large.png 1600w, img/undraw_happy_music-1000_large.png 1000w, img/undraw_happy_music-800_medium.png 800w, img/undraw_happy_music-500_small.png 500w" sizes="50vw" src="img/undraw_happy_music-1600_large.png" alt="happy music bird" >

CSS

img#bird { transition: width 0.5s; max-width: 50vw; } /* Muestra la imagen a la mitad del ancho del viewport */

happy music bird
Fuente: unDraw

El valor del tamaño coincide con el valor del ancho máximo de la imagen en el CSS. Ahora, el navegador tiene todo lo que necesita para escoger la versión correcta de la imagen. El navegador conoce tanto el ancho de su propio viewport como la densidad de píxels del dispositivo del usuario, y le hemos dado las dimensiones de los archivos fuente (mediante el descriptor de anchura) y los tamaños de imagen relativos al viewport (mediante el atributo size).

Variable ¿Conocido por el autor cuando está escribiendo el código? ¿Conocido por el navegador cuando está cargando la página?
dimensiones del viewport no
tamaño de la imagen relativo al viewport no ¡sí! via sizes
densidad de píxels de la pantalla no
tamaño de las imágenes fuente no ¡sí! via srcset

¿Quién conoce qué? Fuente: Srcset and sizes

Atributo
sizes
38.0
16.0
38.0
25.0
9.0

Primera versión del navegador que soporta totalmente la propiedad. Fuente: Can I Use


4. Usando media queries

Se puede usar media queries para redimensionar imágenes en tiempo real en función del ancho del viewport.

HTML

<img id="bird" srcset="img/undraw_happy_music-1600_large.png 1600w, img/undraw_happy_music-1000_large.png 1000w, img/undraw_happy_music-800_medium.png 800w, img/undraw_happy_music-500_small.png 500w" sizes="(max-width: 700px) 90vw, 50vw" src="img/undraw_happy_music-1600_large.png" alt="happy music bird" >

CSS

@media screen and (max-width: 700px) { img#bird { max-width: 90vw; width: 90vw; } }
happy music bird
Fuente: unDraw

La media query comprueba la anchura del viewport de la pantalla, y aplica el CSS si el ancho del viewport es menor de 700px. Se puede informar al navegador sobre la media query en el atributo sizes para que obtenga la imagen correcta cuando esta cambie de tamaño.

Regla
@media
4.0
12.0
2.0
10.0
3.1

Primera versión del navegador que soporta totalmente la regla. Fuente: Can I Use


5. Opcional: usando los elementos picture y source

Se puede usar el elemento <picture> y el elemento <source>, en combinación con media queries, para cambiar la fuente de la imagen a medida que la ventana cambia de tamaño.

<picture>

<source media="(min-width: 750px)" srcset="img/undraw_happy_music-1600_large.png 2x, img/undraw_happy_music-1000_large.png" />

<source media="(min-width: 500px)" srcset="img/undraw_happy_music-800_medium.png" />

<img src="img/undraw_happy_music-500_small.png" alt="happy music bird" />

</picture>
happy music bird
Fuente: unDraw

El elemento <picture> permite definir varios archivos fuente mediante la etiqueta <source>. Difiere del uso directo del atributo srcset en la etiqueta <img> en que <source> permite añadir cosas como media queries a cada conjunto de fuentes. En lugar de dar al navegador los tamaños de imagen y dejar que decida cuál usar, permite definir qué imagen usar para cada tamaño de ventana.

En el código anterior, a partir de 750px, el navegador obtiene undraw_happy_music-1600_large.png (si el dispositivo tiene una pantalla 2x) o img/undraw_happy_music-1000_large.png. Si la anchura de la ventana es inferior a 750px pero superior a 500px, el navegador obtiene img/undraw_happy_music-800_medium.png. Si el ancho de la ventana es inferior a 500px, el navegador obtiene la imagen de reserva img/undraw_happy_music-500_small.png.

Nota: Si el navegador no soporta el elemento <picture>, obtiene lo que haya en el elemento <img>. <picture> sirve únicamente para especificar múltiples fuentes para el contenido de <img>. Es el elemento <img> el que muestra la imagen.

Elemento/valor
figure
8.0
12.0
4.0
11.5
5.1
picture
38.0
13.0
38.0
25.0
9.1
source
90.0
12.0
3.5
75.0
14.1
profundidad de píxel
4.0
12.0
2.0
12.1
3.1

Primera versión del navegador que soporta totalmente el elemento o el valor. Fuente: Can I Use


6. Otros formatos de imagen: svg y webp

Uno de los principales beneficios de SVG es que son independientes de la resolución. Esto significa que, a diferencia de los tipos de archivos como jpg o png, los svg conservan la misma calidad sin importar en qué resolución de pantalla o tamaño estén.

El uso de svg puede resultar en tamaños de archivo más pequeños que otros tipos de archivos cuando se optimizan correctamente. Esto es útil cuando se trata de pantallas de mayor resolución, ya que los svg no necesitan crearse en tamaños más grandes para adaptarse a la diferencia como lo hacen las imágenes rasterizadas. Al tener un tamaño de archivo más pequeño, y por tanto más ligero, la imagen se cargará más rápido.

<picture>

<source srcset="img/undraw_happy_music.svg" type="image/svg+xml" />

<img src="img/undraw_happy_music-1600_large.png" alt="happy music bird" />

</picture>
happy music bird
Fuente: unDraw

El formato de imagen WebP fue desarrollado por Google. Su principal ventaja: permite obtener una excelente definición sin que el archivo sea demasiado pesado. Esto es esencial para la velocidad de carga de las páginas.

Reduce el tamaño de las imágenes hasta un 35% para JPEG y un 50% para PNG, obteniendo archivos más ligeros sin perder su calidad original. Además, admite canal de transparencia.

Otra ventaja es que, al ser un formato de Google mejora el SEO en su buscador.

<picture>

<source srcset="img/undraw_happy_music.webp" type="image/webp" />

<img src="img/undraw_happy_music-1600_large.png" alt="happy music bird" />

</picture>
happy music bird
Fuente: unDraw
Formato
svg
28.0
12.0
4.0
10.0
9.0
webp
32.0
18.0
65.0
19.0
--

Primera versión del navegador que soporta totalmente el formato usando <img>. Fuente: Can I Use


7. Rendimiento (Chrome y Firefox)

Chrome Network tool
Rendimiento de imágenes en local (Chrome)
Firefox Network tool
Rendimiento de imágenes en GitHub (Firefox)

La imagen escogida no es muy pesada, aún así el tiempo de respuesta tiende a reducirse al escoger un tamaño de imagen más acorde al dispositivo y/o viewport.

El formato más ligero y más rápido en cargar es SVG, seguido de WebP.

Nota: Los navegadores pueden tener guardadas las imágenes en caché, conviene limpiarlo antes de monitorizar el rendimiento y desactivarlo mientras las herramientas de desarrollador estén abiertas.


Bonus: rendimiento CSS comprimido vs CSS sin comprimir

Firefox Network tool
Velocidad de carga y número de solicitudes del CSS sin comprmir (GitHub)
Firefox Network tool
Velocidad de carga y número de solicitudes del CSS comprimido (GitHub)

Pese a ser un CSS corto y sencillo hay una diferencia en el tiempo de carga de 9 milisegundos entre ambas versiones y realiza una solicitud menos.

Nota: GitHub bloquea la carga de la fuente de iconos de Creative Commons. Se visualiza igualmente porque existe una copia en local como fuente alternativa.