Generadores de sitios, frameworks y CMS

Descubre cómo los CMS, como WordPress y otros generadores de sitios, pueden facilitar el uso de imágenes responsivas.

Si bien es una mejora respecto de guardar manualmente cortes alternativos de cada imagen y optimizarlos manualmente a través de una herramienta como Squoosh.app, automatizar la compresión de imágenes como paso del proceso de desarrollo tiene algunas limitaciones. Por un lado, es posible que no siempre tengas control total sobre las imágenes que se usan en un sitio. La mayoría de las imágenes para el usuario en la Web están relacionadas más con el contenido que en cuestiones de desarrollo que suben los usuarios o editores, en lugar de vivir en un repositorio junto con recursos de desarrollo como JavaScript y hojas de estilo.

Por lo general, se necesita más de un proceso para la administración de imágenes: una tarea de nivel de desarrollo para los recursos de imagen que se usan en la creación y el mantenimiento de un sitio (fondos, íconos, logotipos, etc.) y otra relacionada con recursos de imagen generados mediante el uso del sitio, como fotografías incorporadas en una publicación por un equipo editorial o un avatar subido por un usuario. Si bien el contexto puede diferir, los objetivos finales son los mismos: codificación y compresión automatizadas según la configuración definida por el equipo de desarrollo.

Por suerte, las bibliotecas de procesamiento de imágenes que comprendes a partir de los flujos de trabajo de desarrollo locales se pueden usar en todos los contextos. Y, si bien nunca puede haber un enfoque único para el lenguaje de marcado de imágenes responsivas, estos sistemas proporcionan valores predeterminados, opciones de configuración y enlaces de API sensibles para facilitar su implementación.

Generadores de sitios estáticos

En comparación con los ejecutores de tareas, existe cierta similitud en la forma en que los generadores de sitios estáticos, como Jekyll o Eleventy, abordan las imágenes. El uso de estas herramientas a fin de producir un sitio web listo para la implementación requiere la administración de recursos, lo que incluye la reducción o la transpilación de CSS y la agrupación de JavaScript. Como puedes imaginar, estas herramientas te permiten procesar recursos de imagen de la misma manera, utilizando muchas de las bibliotecas que ya aprendiste.

El complemento de imágenes oficial para Eleventy usa Sharp para proporcionar cambios de tamaño, generación de varios tamaños de fuente, recodificación y compresión, al igual que algunas de las tareas que aprendiste aquí.

A diferencia del ejecutor de tareas, el generador de sitios estático tiene información directa sobre la configuración y el uso de esas bibliotecas, además del lenguaje de marcado que se genera para el sitio de producción. Esto significa que puede hacer mucho más para automatizar el lenguaje de marcado de imágenes responsivas. Por ejemplo, cuando se invoca como parte de un código corto para mostrar imágenes, este complemento genera HTML de acuerdo con las opciones de configuración que se pasan a Sharp.


const Image = require("@11ty/eleventy-img");
module.exports = function(eleventyConfig) {

async function imageShortcode(src, alt, sizes="100vw") {
  let metadata = await Image(src, {
  formats: ["avif", "webp", "jpeg"],
  widths: [1000, 800, 400],
  outputDir: "_dist/img/",
  filenameFormat: function( id, src, width, format, options ) {
      const ext = path.extname( src ),
        name = path.basename( src, ext );

      return `${name}-${width}.${format}`
  }
  });

  let imageAttributes = {
  alt,
  sizes,
  loading: "lazy"
  };

  return Image.generateHTML(metadata, imageAttributes);
}

eleventyConfig.addAsyncShortcode("respimg", imageShortcode);
};

Luego, se podría usar este código corto en lugar de la sintaxis de imagen predeterminada:

{‌% respimg "img/butterfly.jpg", "Alt attribute.", "(min-width: 30em) 800px, 80vw" %}

Si se configura para generar varias codificaciones, como se muestra más arriba, el lenguaje de marcado generado será un elemento <picture> que contiene los elementos <source> correspondientes, los atributos type y los atributos srcset ya completados con una lista de tamaños candidatos generados.

<picture><source type="image/avif" srcset="/img/butterfly-400.avif 400w, /img/butterfly-800.avif 800w, /img/butterfly-1000.avif 1000w" sizes="(min-width: 30em) 800px, 80vw"><source type="image/webp" srcset="/img/butterfly-400.webp 400w, /img/butterfly-800.webp 800w, /img/butterfly-1000.webp 1000w" sizes="(min-width: 30em) 800px, 80vw"><source type="image/jpeg" srcset="/img/butterfly-400.jpeg 400w, /img/butterfly-800.jpeg 800w, /img/butterfly-1000.jpeg 1000w" sizes="(min-width: 30em) 800px, 80vw"><img alt="Alt attribute." loading="lazy" src="/img/butterfly-400.jpeg" width="1000" height="846"></picture>

Por supuesto, este complemento no podrá generate un atributo sizes viable, ya que no conoce el tamaño ni la posición finales de la imagen en el diseño renderizado, pero acepta uno como entrada cuando genera el lenguaje de marcado, otro trabajo para RespImageLint.

Frameworks

Los frameworks de procesamiento del cliente necesitarán un agrupador o un ejecutor de tareas como Webpack para editar, codificar y comprimir los propios recursos de imagen. Por ejemplo, el cargador responsivo también usa la biblioteca de Sharp para volver a guardar los recursos de imagen. Luego, te permite import tus imágenes como objetos:

  import imageAVIF from 'img/butterfly.jpg?sizes[]=400,sizes[]=800,sizes[]=1000&format=avif';
  import imageWebP from 'img/butterfly.jpg?sizes[]=400,sizes[]=800,sizes[]=1000&format=webp';
  import imageDefault from 'img/butterfly.jpg?sizes[]=400,sizes[]=800,sizes[]=1000';

Estas imágenes importadas se pueden usar con abstracciones como Componente de imagen de React o para propagar directamente el lenguaje de marcado de imágenes responsivas:

<picture>
  <source type='image/avif' srcSet={imageAVIF.srcSet} sizes='…' />
  <source type='image/webp' srcSet={imageWebp.srcSet} sizes='…' />
  <img
    src={imageDefault.src}
    srcSet={imageDefault.srcSet}
    width={imageDefault.width}
    height={imageDefault.height}
    sizes='…'
    loading="lazy"
  />

Un framework que realiza la renderización del cliente es un gran candidato para Lazysizes y sizes="auto", lo que te brinda imágenes responsivas casi completamente automatizadas.

Sistemas de administración de contenido

WordPress fue uno de los primeros usuarios del lenguaje de marcado de imágenes responsivas nativas. Además, la API se mejoró gradualmente desde su presentación en WordPress 4.4 con compatibilidad con WebP y control del tipo de MIME de salida. El núcleo de WordPress está diseñado para usar la extensión de PHP de ImageMagick (o, de lo contrario, la biblioteca de GD).

Cuando se sube una imagen a través de la interfaz de administrador de WordPress, esa imagen de origen se usa para generar archivos orientados al usuario en el servidor, de manera muy similar a como lo harías en tu máquina local. De forma predeterminada, cualquier salida de imagen de WordPress vendrá con un atributo srcset generado basado en los tamaños de imagen configurados en tu tema.

Hay dos parámetros de configuración clave que se pueden ajustar para las imágenes generadas son la calidad de la compresión y el tipo de MIME de salida.

Por ejemplo, para establecer la calidad de compresión predeterminada en 70 para todas las imágenes generadas, usa lo siguiente:

add_filter( 'wp_editor_set_quality', function() { return 70; } );

Para lograr una compresión aún mejor, cambia el formato de salida de las imágenes JPEG subidas a WebP con lo siguiente:

add_filter( 'image_editor_output_format', function( $mappings ) {
  $mappings[ 'image/jpeg' ] = 'image/webp';
    return $mappings;
} );

Debido a que WordPress comprende todos los cortes alternativos y las codificaciones que genera a partir de una imagen subida, puede proporcionar funciones auxiliares, como wp_get_attachment_image_srcset(), para recuperar el valor srcset completo y generado de una imagen adjunta.

Como es probable que ya hayas adivinado, trabajar con el atributo sizes es un poco más complicado. Al no contar con información sobre cómo se usarán las imágenes en un diseño, WordPress establece de forma predeterminada un valor sizes que indica efectivamente que "esta imagen debe ocupar el 100% del viewport disponible, hasta el mayor tamaño intrínseco de la fuente", un valor predeterminado predecible, pero no correcto para ninguna aplicación real. Asegúrate de usar wp_calculate_image_sizes() para establecer atributos sizes adecuados para el contexto en tus plantillas.

Por supuesto, hay innumerables complementos de WordPress que se dedican a acelerar los flujos de trabajo de imágenes modernos para los equipos de desarrollo y los usuarios. Quizás lo más interesante es que los complementos como el Acelerador de sitios de Jetpack (antes llamado "Photon") pueden realizar negociaciones del servidor para la codificación, lo que garantiza que los usuarios reciban la codificación más pequeña y eficiente que su navegador pueda admitir sin necesidad de patrones de lenguaje de marcado <picture> y type. Para ello, usa una red de distribución de contenidos de imágenes (una tecnología que puedes usar por tu cuenta, independientemente de tu CMS).

Todo esto también se aplica a las soluciones de CMS alojadas, como Shopify, aunque los mecanismos en sí difieren un poco: ofrecen hooks similares para generar fuentes de imagen alternativas y atributos srcset correspondientes y dirección artística a través del elemento <picture>.