Automatiza la compresión y la codificación

Haz que la generación de fuentes de imágenes de alto rendimiento sea una parte continua de tu de desarrollo de software.

Todas las sintaxis de este curso, desde la codificación de datos de imágenes hasta lenguaje de marcado que potencia las imágenes responsivas: son métodos para que las máquinas se comuniquen con las máquinas. Tienes descubrieron varias formas para que el navegador de un cliente comunique sus necesidades a un servidor y que un servidor responda de la misma manera. El lenguaje de marcado de imágenes responsivas (en particular, srcset y sizes) logra describir una cantidad impactante de información en relativamente pocos caracteres. Lo bueno o lo peor es que la brevedad se deba a un diseño específico: hace que estas sintaxis sean menos concisas y más fáciles para los desarrolladores. analizarlas, podrían haberlas hecho más difíciles de analizar para un navegador. Cuanta más complejidad se agregue a una cadena, más hay errores del analizador o diferencias no intencionales en el comportamiento de un navegador a otro.

Una ventana de codificación de imagen automatizada

Sin embargo, el mismo rasgo que puede hacer que estos sujetos se sientan tan intimidantes también puede proporcionarte soluciones: una sintaxis fácil read (leído por las máquinas) es una sintaxis que ellas le escriben más fácilmente. Es casi seguro que hayas encontrado muchos ejemplos de modelos Codificación y compresión de imágenes como un usuario de la Web: cualquier imagen subida a la Web a través de plataformas de redes sociales, contenido (CMS) y hasta clientes de correo electrónico pasarán casi siempre por un sistema que cambia de tamaño, vuelve a codificar y los comprime.

Del mismo modo, ya sea a través de complementos, bibliotecas externas, herramientas de procesos de compilación independientes o el uso responsable de secuencias de comandos del cliente, el lenguaje de marcado de imágenes responsivas se presta fácilmente a la automatización.

Esas son las dos preocupaciones principales en torno a la automatización del rendimiento de las imágenes: administrar la creación de imágenes (su codificación, y las fuentes alternativas que usarás para propagar un atributo srcset y generar nuestro lenguaje de marcado para el usuario. En este módulo, conocerás algunos enfoques comunes para administrar imágenes como parte de un flujo de trabajo moderno, ya sea en la fase automatizada de tu proceso de desarrollo, mediante el marco de trabajo o el sistema de administración de contenido que potencia tu sitio casi completamente abstraídos por una red dedicada de distribución de contenidos.

Automatización de la compresión y la codificación

Es poco probable que te encuentres en una posición en la que puedas tomarte el tiempo para determinar manualmente la codificación y el nivel ideales. de compresión para cada imagen individual destinada a usarse en un proyecto, ni querrías hacerlo. Como Mantener los tamaños de transferencia de imágenes tan pequeños como sea posible , mejorando la configuración de compresión y volver a guardar fuentes alternativas para cada recurso de imagen destinado a un sitio web de producción introduciría un gran cuello de botella en tu trabajo diario.

Como aprendiste al leer sobre los diversos formatos de imagen y tipos de compresión, la codificación más eficiente para una imagen siempre estará dictada por para comprender su contenido y, como vimos en la sección Imágenes responsivas, los tamaños alternativos que necesitarás para las fuentes de imágenes serán según la posición que ocupan esas imágenes en el diseño de la página. En un flujo de trabajo moderno, abordarás estas decisiones de manera integral y no individual, lo que permite determinar un conjunto de valores predeterminados razonables para las imágenes, a fin de que se adapten mejor a los contextos están diseñados para usarse.

A la hora de elegir codificaciones para un directorio de imágenes fotográficas, AVIF es el ganador claro en cuanto a calidad y tamaño de transferencia. pero tiene compatibilidad limitada, WebP proporciona un resguardo moderno y optimizado, y JPEG es el valor predeterminado más confiable. La herramienta los tamaños que necesitamos producir para las imágenes que ocupan una barra lateral en un diseño de página variarán mucho de las imágenes que ocupe todo el viewport del navegador en nuestros puntos de interrupción más altos. La configuración de compresión requerirá un ojo para desenfocar artefactos de compresión en varios archivos resultantes, lo que deja menos espacio para dividir cada byte posible de cada imagen. a cambio de un flujo de trabajo más flexible y confiable. En resumen, seguirás el mismo proceso de toma de decisiones que comprender en este curso, escribir en grande.

En cuanto al procesamiento en sí, hay una gran cantidad de bibliotecas de procesamiento de imágenes de código abierto que proporcionan convertir, modificar y editar imágenes en lotes, para competir en cuanto a velocidad, eficiencia y confiabilidad. Estos procesamientos te permitirán aplicar parámetros de configuración de codificación y compresión a directorios completos de imágenes a la vez, sin la un software de edición de imágenes y de una manera que conserve las fuentes de imágenes originales en caso de que esos ajustes que se ajusten sobre la marcha. Están diseñadas para ejecutarse en una variedad de contextos, desde tu entorno de desarrollo local hasta el servidor web en sí, por ejemplo, la ImageMin centrada en la compresión para Node.js se puede extender para que se adapte a aplicaciones específicas a través de un array de complementos. mientras que la multiplataforma ImageMagick y Sharp basada en Node.js incluye una asombrosa cantidad de funciones desde el primer momento.

Estas bibliotecas de procesamiento de imágenes permiten que los desarrolladores compilen herramientas dedicadas a optimizar imágenes sin problemas como parte de los procesos de desarrollo estándar; asegúrate de que tu proyecto siempre haga referencia a la imagen lista para la producción con la menor sobrecarga posible.

Herramientas de desarrollo y flujos de trabajo locales

Los ejecutores de tareas y agrupadores como Grunt, Gulp o Webpack se pueden usar para lo siguiente: optimizar los recursos de imagen junto con otras tareas comunes relacionadas con el rendimiento, como la reducción de CSS y JavaScript. Para A modo de ejemplo, tomemos un caso de uso relativamente simple: un directorio de tu proyecto contiene una docena de imágenes fotográficas, que debe usarse en un sitio web público.

En primer lugar, debes asegurarte de que la codificación de estas imágenes sea coherente y eficiente. Como vimos en los módulos anteriores, WebP es un valor predeterminado eficiente para imágenes fotográficas en términos de calidad y tamaño de archivo. WebP es compatible. pero no es compatible universamente, por lo que también te recomendamos incluir un resguardo en forma de JPEG progresivo. Luego, Si quieres usar el atributo srcset para enviar estos recursos de forma eficiente, deberás producir varios tamaños alternativos para cada codificación.

Si bien esta sería una tarea repetitiva y que demanda mucho tiempo si se hace con software de edición de imágenes, a los ejecutores de tareas, como Gulp están diseñados para automatizar exactamente este tipo de repetición. La API de gulp responsivo que hace uso de Sharp, es una opción entre muchas que siguen un patrón similar: recopilando todos los archivos en un directorio del código fuente, volviendo a codificarlos y comprimiéndolos en función de la misma “calidad” estandarizada. abreviatura que aprendiste en Formatos de imagen y compresión. Los archivos resultantes se envían a una ruta que definas. Listo para que se pueda hacer referencia a él en los atributos src de los elementos img para el usuario y dejar los archivos originales intactos.

const { src, dest } = require('gulp');
const respimg = require('gulp-responsive');

exports.webp = function() {
  return src('./src-img/*')
    .pipe(respimg({
      '*': [{
        quality: 70,
        format: ['webp', 'jpeg'],
        progressive: true
      }]
  }))
  .pipe(dest('./img/'));
}

Con un proceso como este implementado, no se haría daño a un entorno de producción si alguien en el proyecto inadvertidamente agregaste una fotografía codificada como un PNG masivo de truecolor al directorio que contiene las fuentes de las imágenes originales, independientemente de la codificación de la imagen original, esta tarea producirá un resguardo eficiente de WebP y un resguardo de JPEG progresivo confiable, y a un de compresión que se puede ajustar sobre la marcha. Este proceso también garantiza que la imagen original los archivos se conservarán en el entorno de desarrollo del proyecto, lo que significa que esta configuración puede ajustarse en cualquier tiempo solo con los resultados automáticos reemplazados.

Para generar varios archivos, debes pasar varios objetos de configuración, todos iguales, excepto por la adición de Una clave width y un valor en píxeles:

const { src, dest } = require('gulp');
const respimg = require('gulp-responsive');

exports.default = function() {
  return src('./src-img/*')
    .pipe(respimg({
    '*': [{
            width: 1000,
            format: ['jpeg', 'webp'],
            progressive: true,
            rename: { suffix: '-1000' }
            },
            {
            width: 800,
            format: ['jpeg', 'webp'],
            progressive: true,
            rename: { suffix: '-800' }
            },
            {
            width: 400,
            format: ['jpeg', 'webp'],
            progressive: true,
            rename: { suffix: '-400' },
        }]
        })
    )
    .pipe(dest('./img/'));
}

En el caso del ejemplo anterior, la imagen original (monarch.png) tenía más de 3.3 MB. El archivo más grande generado por esta tarea (monarch-1000.jpeg) es de aproximadamente 150 KB. La más pequeña, monarch-400.web, pesa solo 32 KB.

[10:30:54] Starting 'default'...
[10:30:54] gulp-responsive: monarch.png -> monarch-400.jpeg
[10:30:54] gulp-responsive: monarch.png -> monarch-800.jpeg
[10:30:54] gulp-responsive: monarch.png -> monarch-1000.jpeg
[10:30:54] gulp-responsive: monarch.png -> monarch-400.webp
[10:30:54] gulp-responsive: monarch.png -> monarch-800.webp
[10:30:54] gulp-responsive: monarch.png -> monarch-1000.webp
[10:30:54] gulp-responsive: Created 6 images (matched 1 of 1 image)
[10:30:54] Finished 'default' after 374 ms

Por supuesto, deberás examinar cuidadosamente los resultados en busca de artefactos de compresión visibles o, tal vez, aumentar la compresión. para ahorrar más. Como esta tarea no es destructiva, esta configuración se puede cambiar fácilmente.

En definitiva, a cambio de los pocos kilobytes que se pueden extraer con una cuidadosa microoptimización manual, se obtiene un proceso que no solo es eficiente, sino resiliente; es una herramienta que aplica sin problemas tus conocimientos sobre recursos de imagen de alto rendimiento a todo un proyecto, sin ninguna intervención manual.

Lenguaje de marcado de imágenes responsivas en práctica

Propagar atributos srcset suele ser un proceso manual sencillo, ya que el atributo en realidad solo captura información sobre la configuración que ya aplicaste al generar tus fuentes. En las tareas anteriores, establecimos los nombres de archivo y la información de ancho que seguirá nuestro atributo:

srcset="filename-1000.jpg 1000w, filename-800.jpg 800w, filename-400.jpg 400w"

Recuerda que el contenido del atributo srcset es descriptivo, no prescriptivo. Sobrecargar una srcset, siempre que la relación de aspecto de cada fuente sea coherente. Un atributo srcset puede contener el URI y ancho de cada corte alternativo generado por el servidor sin causar solicitudes innecesarias, y los candidatos que proporcionamos para una imagen procesada, más eficientemente podrá el navegador adaptar las solicitudes.

Como aprendiste en Imágenes responsivas, es recomendable que uses el elemento <picture> para manejar sin problemas el archivo WebP o JPEG. En este caso, usarás el atributo type junto con srcset.

<picture>
  <source type="image/webp" srcset="filename-1000.webp 1000w, filename-800.webp 800w, filename-400.webp 400w">
  <img srcset="filename-1000.jpg 1000w, filename-800.jpg 800w, filename-400.jpg 400w" sizes="…" alt="…">
</picture>

Como aprendiste, los navegadores que admiten WebP reconocerán el contenido del atributo type y seleccionarán <source> el atributo srcset del elemento como la lista de imágenes candidatas. Navegadores que no reconocen image/webp como contenido multimedia válido tipo ignorará este <source> y, en su lugar, usará el atributo srcset del elemento <img> interno.

Hay una consideración más con respecto a la compatibilidad con los navegadores: los navegadores sin compatibilidad con lenguaje de marcado de imagen responsiva necesitar un resguardo, o bien correr el riesgo de que se dañe una imagen en contextos de navegación muy antiguos. Como <picture>, <source> y srcset se ignoran en estos navegadores, por lo que deberás especificar una fuente predeterminada en el archivo <img> interno src.

Debido a que escalar una imagen hacia abajo es visualmente fluido y la codificación JPEG es compatible universalmente, el JPEG más grande es una elección sensata.

<picture>
  <source type="image/webp" srcset="filename-1000.webp 1000w, filename-800.webp 800w, filename-400.webp 400w">
  <img src="filename-1000.jpg" srcset="filename-1000.jpg 1000w, filename-800.jpg 800w, filename-400.jpg 400w" sizes="…" alt="…">
</picture>

sizes puede ser un poco más difícil de manejar. Como aprendiste, sizes es necesariamente contextual: puedes No se puede completar el atributo sin conocer la cantidad de espacio que debe ocupar la imagen en el diseño renderizado. Para para realizar las solicitudes más eficientes, debe incluir un atributo sizes preciso en nuestro lenguaje de marcado en el momento en que se envíen esas solicitudes son realizadas por el usuario final, mucho antes de que se hayan solicitado los estilos que rigen el diseño de la página. Se omite sizes por completo. no solo es un incumplimiento de la especificación HTML, sino que da como resultado un comportamiento predeterminado equivalente a sizes="100vw", lo que informa al navegador que esta imagen solo está restringida por la vista del puerto, lo que da como resultado las fuentes candidatos más grandes posibles que se está seleccionando.

Como sucede con cualquier tarea de desarrollo web particularmente compleja, se han creado diversas herramientas para abstraer el proceso de escritura a mano de los atributos sizes respImageLint es un Es el fragmento de código esencial para examinar la exactitud de tus atributos de sizes y proporcionar sugerencias de mejoras. Se ejecuta como unbookmarklet, una herramienta que se ejecuta en el navegador, mientras apunta a la página totalmente renderizada que contiene la imagen o de terceros. En un contexto en el que el navegador comprende plenamente el diseño de la página, también tendrá imágenes casi perfectas de píxeles. conocimiento del espacio que debe ocupar una imagen en ese diseño en todos los tamaños de viewport posibles.

El informe de imágenes responsivas muestra una discrepancia de tamaño y ancho.

Una herramienta para analizar con lint tus atributos sizes es muy útil, pero tiene aún más valor como herramienta para generarlos por completo. Como sabes, las sintaxis srcset y sizes están diseñadas para optimizar las solicitudes de recursos de imagen de una manera visualmente fluida. Sin embargo, No es algo que deba usarse en producción, un valor predeterminado de marcador de posición sizes de 100vw es perfectamente razonable. mientras trabajas en el diseño de una página en tu entorno de desarrollo local. Una vez que se implementen los estilos de diseño, se ejecutará respImageLint te proporcionará atributos sizes personalizados que puedes copiar y pegar en tu lenguaje de marcado, con un nivel de detalle mucho mayor más de uno escrito a mano:

Informe de imágenes responsivas con las dimensiones sugeridas.

Aunque las solicitudes de imagen iniciadas por el lenguaje de marcado renderizado por el servidor ocurren demasiado rápido como para que JavaScript genere un atributo sizes del cliente, no se aplica el mismo razonamiento si esas solicitudes se inician en el cliente. El proyecto Lazysizes, por ejemplo, te permite diferir por completo las solicitudes de imágenes hasta que se haya establecido el diseño, lo que permite que JavaScript genere nuestros valores de sizes para nosotros, una gran conveniencia y una garantía de las solicitudes más eficientes posibles para tus usuarios. Sin embargo, ten en cuenta que este enfoque implica sacrificar la confiabilidad del lenguaje de marcado renderizado por el servidor y la velocidad optimizaciones incorporadas en los navegadores, y el inicio de estas solicitudes solo después de que la página se haya renderizado mostrará una imagen un impacto negativo en tu puntuación de LCP.

Por supuesto, si ya dependes de un framework de renderización del lado del cliente, como React o Vue, esa es una deuda con la que cuenta. y, en esos casos, el uso de tamaños diferidos significa que tus atributos sizes se pueden abstraer casi por completo. Mejor aún: a medida que sizes="auto" en imágenes de carga diferida gana consenso y implementaciones nativas, Lazysizes se convertirán en un polyfill para el comportamiento recientemente estandarizado del navegador.