Adaptive Images

Mario González - Blog sobre desarrollo web

Adaptive Images – Imágenes para responsive web design

| ,

En la actualidad aún no hay una solución ideal y sin problemas asociados para utlizar imágenes en responsive web design. Sin embargo, hay muchas propuestas, cada una con sus ventajas e inconvenientes, que nos permiten incluir imágenes flexibles en nuestros diseños. Podemos ver un listado de todas las técnicas que están recopilando Chris Coyier y Christopher Schmitt en esta hoja de cálculo de Google.

En este artículo vamos a hablar de una de estas soluciones: Adaptive Images. Veremos en qué se basa su funcionamiento, qué tenemos que hacer para implementarla y qué ventajas y desventajas tiene.

El problema

Como vimos en el anterior post Responsive web design, es muy fácil conseguir que las imágenes sean flexibles y que se escalen junto con las dimensiones del navegador. Para ello, basta con añadir estas líneas de CSS a las imágenes que queramos convertir en flexibles:


max-width:100%;
height:auto;

Con estas reglas, la imagen siempre tendrá, como máximo, el ancho que le deja libre su contenedor. Así, si se reduce el contenedor, se reduce la imagen. Hay excepciones como ésta, y por supuesto, si queremos que funcione en navegadores antiguos, habrá que añadir algunas cosas.

Sin embargo, esta técnica presenta un problema: si nuestra imagen original mide 600px y vemos la página desde un dispositivo móvil con una resolución de 320px, la imagen se escalará correctamente, pero habremos descargado información de más. Mientras que nuestro responsive design hará sus deberes y mostrará la imagen a 200px, por ejemplo, el navegador habrá tenido que descargar una imagen de 600px. Teniendo en cuenta las velocidades de las conexiones 3G, podemos tener una diferencia notable en el tiempo de carga de la web. Lo óptimo sería descargar una imagen de 200px, que pesará bastante menos que la de 600px.

Una de las soluciones

Se han propuesto varias soluciones al problema del ancho de banda desperdiciado con las imágenes flexibles, varias de ellas basándose en el principio de cargar una imagen u otra según la resolución. Para entender las diferencias entre ellas, recomendamos la lectura del artículo Which responsive images solution should you use?

Nos centraremos en una de las soluciones: Adaptive Images. Es una solución del lado del servidor, que utiliza PHP, .htaccess y un mínimo de JavaScript. Puede parecer que tiene demasiadas dependencias, pero en realidad el PHP es un simple script que sólo tenemos que colocar en el directorio raíz del servidor, la parte de .htaccess sólo nos requerirá añadir un par de líneas al .htaccess que probablemente ya tengamos, y el JavaScript es una sola línea en el header de nuestro documento HTML. Lo mejor de todo es que sólo hay que instalarlo, decirle cuáles son nuestros puntos de corte en las media queries, y verlo funcionar. No necesitamos tocar nada en el código HTML.

¿Cómo funciona?

Adaptive Images basa su funcionamiento en una redirección que hará pasar todas las peticiones de imágenes a través del script PHP, gracias a mod_rewrite. Este script PHP es el que devolverá una imagen u otra según el ancho del navegador. Veamos el proceso completo.

Para empezar, una línea de JavaScript en el header del documento HTML se encarga de mirar las dimensiones del navegador y de almacenarlas en una cookie. La cookie permite la comunicación entre JavaScript y PHP, ya que es accesible tanto desde el cliente como desde el servidor (porque el navegador la envía junto con la petición). Como decíamos, el JavaScript guarda las dimensiones del navegador, pero realmente en realidad guarda sólo una: o el ancho o el alto, la mayor de las dos. Más adelante explicaremos por qué.

Cuando el navegador realiza las peticiones de las imágenes al servidor, éste no las entrega; en su lugar llama al script PHP adaptive-images.php. Esto lo hace porque en el .htaccess le hemos añadido una redirección: le hemos dicho al módulo mod_rewrite que todas las peticiones de archivos con extensión gif, jpeg, jpg o png las redirija al archivo adaptive-images.php. Bueno, en realidad no todas, en el .htaccess podemos determinar en qué carpetas no debería ocurrir esa redirección (es decir, en qué carpeta están guardadas las imágenes que no queremos convertir en flexibles).

Cuando se ejecuta el script PHP, lo primero que hace éste es consultar en la cookie (que ha creado o actualizado previamente el JavaScript) la resolución del navegador. Una vez que tiene este dato, busca en los puntos de corte que le hemos definido para saber a cuál corresponde la resolución actual. Lo normal es que los puntos de corte se correspondan con los que hemos usado en nuestras media queries en CSS.

Por ejemplo, si tenemos estos puntos de corte:


@media only screen and (max-width:1150px) {

}
@media only screen and (max-width:900px) {

}
@media only screen and (max-width:600px) {

}

Entonces guardaremos esos mismos valores en el script PHP (esto sólo hay que hacerlo una vez):


$resolutions = array(1150, 900, 600);

Así, si el PHP ve que la resolución del navegador es de 720px, elegirá el punto de corte inmediatamente superior, es decir, 900px. Esto quiere decir que la imagen que devolverá medirá 900px de ancho. Así se nos garantiza que la imagen que el navegador se descargará nunca será mayor que lo que puede mostrar.

Volviendo atrás, dijimos que la cookie almacena la mayor de las dos dimensiones, ancho o alto. ¿Por qué no simplemente almacena el ancho, si en realidad es en esta dimensión en la que nos basamos para escalar las imágenes? Es decir, si estamos usando un móvil que en modo portrait mide 320×480, ¿por qué descargar una imagen de 480px y no una de 320px? La respuesta es que si cargamos la de 320px y luego giramos el móvil y cambiamos la orientación a landscape, seguiremos teniendo la de 320px, que probablemente se escalará a más y se verá mal. Por esta razón Adaptive Images siempre carga la mayor imagen que el dispositivo podría necesitar.

Una vez que el script ha decidido el tamaño de la imagen que va a devolver, se va a buscarla al directorio caché, por si ya existiera. Si ya existe, se envía y el navegador recibe y muestra la imagen a la resolución correcta. Si la imagen no existe en el caché, entonces el script se encargará de crear una versión redimensionada de la foto original. Esa versión es la que devolverá, además de guardarla en un directorio caché para posteriores usos.

¿Qué necesitamos?

Para usar Adaptive Images, tenemos que descargar sus dos archivos desde la página de descargas. Una vez descargados, sólo necesitamos tres pasos para tenerlo funcionando:

1. Configurar el .htaccess: si nuestra web no tiene ningún archivo .htaccess, entonces simplemente debemos colocar el .htaccess de la descarga en el directorio raíz de la web. Si ya tenemos uno, sólo tenemos que añadirle las líneas correspondientes al de la descarga, que son las que hacen la redirección de una imagen al archivo adaptive-images.php.


  # Adaptive-Images -----------------------------------------------------------------------------------

  # Add any directories you wish to omit from the Adaptive-Images process on a new line, as follows:
  # RewriteCond %{REQUEST_URI} !ignore-this-directory
  # RewriteCond %{REQUEST_URI} !and-ignore-this-directory-too
 
  RewriteCond %{REQUEST_URI} !assets

  # don't apply the AI behaviour to images inside AI's cache folder:
  RewriteCond %{REQUEST_URI} !ai-cache
    
  # Send any GIF, JPG, or PNG request that IS NOT stored inside one of the above directories
  # to adaptive-images.php so we can select appropriately sized versions
 
  RewriteRule \.(?:jpe?g|gif|png)$ adaptive-images.php

  # END Adaptive-Images -------------------------------------------------------------------------------

2. Configurar el script: en adaptive-images.php hay un array de resoluciones, sólo tenemos que introducirle los mismos valores que tenemos configurados en nuestras media queries, como vimos anteriormente.


$resolutions   = array(1150, 900, 600); // the resolution break-points to use (screen widths, in pixels)

3. Añadir en el header de nuestra página la siguiente línea de JavaScript:



Esta línea es la encargada de guardar la cookie con el valor de la máxima resolución, y tenemos que ponerla antes de cualquier otro JavaScript.

Los detalles de la instalación están explicados en la página de instalación. El paso 3 lo tendremos que realizar en cada página de nuestro sitio, los anteriores sólo una vez.

Ventajas e inconvenientes

Como decíamos antes, hay muchas soluciones al problema de las imaǵenes en responsive design, y ninguna es ideal ni perfecta. Como todas las demás, Adaptive Images tiene sus ventajas y sus desventajas frente al resto.

La principal ventaja de Adaptive Images es que funciona sin tener que tocar código HTML. Esto es una ventaja por dos razones:

  • Si tenemos que convertir en flexibles las imágenes de un sitio web ya existente, sólo tenemos que añadir una línea de JavaScript a la cabecera de cada página. Si nuestra web tiene muchas páginas con imágenes y tuviéramos que retocar cada etiqueta <img>, la diferencia en tiempo de trabajo sería abismal.
  • Conserva la semántica y la validez del código. Con la mayoría de las otras soluciones tenemos que añadir algún atributo o cambiar la etiqueta <img>, comprometiendo tanto la semántica como la validación del código HTML.

Otra de las ventajas principales es que para cada imagen sólo hay una petición y es la definitiva. Con muchas otras soluciones el navegador tiene que cargar primero una versión reducida de la imagen, y luego cargar la grande en caso de que cuadre con la resolución. Esto, aparte de poder provocar un parpadeo en la imagen, no resuelve bien el problema del gasto de ancho de banda innecesario, puesto que en muchos casos se cargan dos imágenes cuando sólo se ve una.

En cuanto a las desventajas, la primera es que es una solución del lado del servidor. Esto implica que necesitamos que el servidor tenga PHP y Apache (por el .htaccess). Además, no todos los desarrolladores web tienen conocimientos de PHP ni son programadores. Y la segunda desventaja es que, al usar la resolución máxima del dispositivo, si tenemos el móvil orientado en modo portrait probablemente estaremos cargando una imagen más grande que el ancho del navegador. Esto tiene su razón de ser, como vimos antes, pero no es la solución óptima si buscamos no descargar más información que la que vamos a ver.

Conclusiones

Aún está por llegar el estándar en cuanto a uso de imágenes en responsive design. Mientras tanto, hay muchas buenas opciones en la red, y Adaptive Images es una de ellas. Por su facilidad de uso es una buena candidata si queremos utilizar imágenes flexibles en nuestros diseños y no desperdiciar ancho de banda.

¿Qué opinas?

Tu dirección de correo electrónico no será publicada. * Campos obligatorios