Automatizar a compactação e a codificação

Torne a geração de fontes de imagens de alto desempenho uma parte perfeita do seu de desenvolvimento de software.

Todas as sintaxes deste curso, desde a codificação de dados de imagem até a densa informação que alimentam as imagens responsivas (link em inglês) são métodos para máquinas se comunicarem com máquinas. Você tem descobriu várias maneiras de um navegador cliente comunicar suas necessidades a um servidor e um servidor responder da mesma forma. A marcação de imagem responsiva (em particular, srcset e sizes) descreve uma quantidade chocante de informações de maneira relativamente poucos caracteres. Para o bem ou para o mal, essa brevidade é incorporada ao design: tornar essas sintaxes menos concisas e, portanto, mais fáceis para os desenvolvedores. de analisar, poderia ter dificultado a análise por um navegador. Quanto mais complexidade for adicionada a uma string, possíveis erros do analisador ou diferenças não intencionais de comportamento de um navegador para outro.

Uma janela automatizada de codificação de imagem.

No entanto, a mesma característica que pode fazer esses assuntos parecerem tão intimidantes também pode fornecer soluções: uma sintaxe mais fácil read por máquinas é uma sintaxe mais facilmente escrita por elas. Você provavelmente já se deparou com vários exemplos de codificação e compactação de imagens como um usuário da web: qualquer imagem enviada para a web através de plataformas de mídia social, conteúdo sistemas de gerenciamento de conteúdo (CMS) e até mesmo clientes de e-mail passam por um sistema que redimensiona, recodifica e os compacta.

Da mesma forma, seja por meio de plug-ins, bibliotecas externas, ferramentas de processo de compilação autônoma ou uso responsável de scripting do lado do cliente, a marcação de imagem responsiva prontamente permite a automação.

Essas são as duas principais preocupações quanto à automatização do desempenho de imagens: gerenciar a criação de imagens – suas codificações, compactação e as fontes alternativas que você vai usar para preencher um atributo srcset e gerar nossa marcação voltada para o usuário. Neste módulo, você vai conhecer algumas abordagens comuns para gerenciar imagens como parte de um fluxo de trabalho moderno, seja como fase automatizada em seu processo de desenvolvimento, por meio da estrutura ou sistema de gerenciamento de conteúdo que alimenta seu site, ou por uma rede de fornecimento de conteúdo dedicada.

Como automatizar a compactação e a codificação

É improvável que você se encontre em uma posição em que possa determinar manualmente a codificação e o nível ideais de compactação para cada imagem destinada ao uso em um projeto, ou você não gostaria. Conforme importante, já que é manter os tamanhos de transferência de imagem o menor possível, ajustando configurações de compactação e salvar novamente fontes alternativas para cada ativo de imagem destinado a um site de produção introduziria um enorme gargalo no seu trabalho diário.

Como você aprendeu ao ler sobre os vários formatos de imagem e tipos de compactação, a codificação mais eficiente para uma imagem será sempre ditada por o conteúdo. Como você aprendeu em Imagens responsivas, os tamanhos alternativos necessários para as origens das imagens serão determinado pela posição dessas imagens no layout da página. Em um fluxo de trabalho moderno, você vai abordar essas decisões de forma holística, e não individual, determinando um conjunto de padrões sensíveis para imagens, a fim de se adaptar melhor aos contextos eles devem ser usados.

Ao escolher codificações para um diretório de imagens fotográficas, o AVIF é, claramente, o vencedor em termos de qualidade e tamanho de transferência mas tem suporte limitado, o WebP fornece um substituto otimizado e moderno, e JPEG é o padrão mais confiável. A alternativa os tamanhos que precisamos produzir para imagens destinadas a ocupar uma barra lateral em um layout de página serão muito diferentes das imagens destinadas para ocupar toda a janela de visualização do navegador nos maiores pontos de interrupção. As configurações de compressão exigem atenção ao desfoque e artefatos de compactação em vários arquivos resultantes, deixando menos espaço para esculpir cada byte possível de cada imagem em troca de um fluxo de trabalho mais flexível e confiável. Resumindo, você vai seguir o mesmo processo de tomada de decisão entenderam em grande escala neste curso.

Quanto ao processamento em si, há um grande número de bibliotecas de processamento de imagens de código aberto que fornecem métodos de conversão, modificação e edição de imagens em lotes, competindo entre velocidade, eficiência e confiabilidade. O processamento permitem que você aplique configurações de codificação e compactação a diretórios inteiros de imagens de uma só vez, sem a precisar abrir um software de edição de imagens e de maneira a preservar as fontes de imagem originais caso essas configurações precisem a ser ajustado instantaneamente. Eles foram feitos para execução em diversos contextos, desde o ambiente de desenvolvimento local até a próprio servidor da Web, por exemplo, o ImageMin, focado em compactação para É possível estender o Node.js para que se adeque a aplicativos específicos usando diversos plug-ins, enquanto o ImageMagick multiplataforma e o Sharp com base em Node.js vêm com um número impressionante de recursos prontos para uso.

Essas bibliotecas de processamento de imagens possibilitam que os desenvolvedores criem ferramentas dedicadas a otimizar imagens perfeitamente como parte de seus processos de desenvolvimento padrão, garantindo que seu projeto sempre faça referência a imagens prontas para produção fontes com o mínimo possível de overhead.

Ferramentas de desenvolvimento e fluxos de trabalho locais

Executores de tarefas e bundlers como Grunt, Gulp ou Webpack podem ser usados para otimizar recursos de imagem junto com outras tarefas comuns relacionadas ao desempenho, como minificação de CSS e JavaScript. Para Para ilustrar, vamos pegar um caso de uso relativamente simples: um diretório em seu projeto contém uma dúzia de imagens fotográficas, deve ser usado em um site público.

Primeiro, você precisará garantir uma codificação consistente e eficiente para essas imagens. Como você aprendeu nos módulos anteriores, WebP é um padrão eficiente para imagens fotográficas em termos de qualidade e tamanho de arquivo. O formato WebP é bem compatível, mas não tem compatibilidade universal, então inclua também um substituto na forma de um JPEG progressivo. Depois, Para usar o atributo srcset e fornecer esses recursos de maneira eficiente, você precisará produzir vários tamanhos alternativos para cada codificação.

Embora essa seja uma tarefa repetitiva e demorada se feita com um software de edição de imagens, os corredores gostam O Gulp foi desenvolvido para automatizar exatamente esse tipo de repetição. O comando gulp-reply O plug-in, que usa a Sharp, é uma opção entre muitas que seguem um padrão semelhante: coletando todos os arquivos em um diretório de origem, recodificando-os e compactando-os com base na mesma "qualidade" padronizada que você aprendeu em Formatos e compactação de imagens. Os arquivos resultantes são enviados para um caminho definido por você, Prontos para serem referenciados nos atributos src dos elementos img voltados ao usuário, deixando os arquivos originais 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/'));
}

Com um processo como esse, nenhum dano seria causado a um ambiente de produção se alguém no projeto inadvertidamente adicionou uma foto codificada como PNG massivo de cores verdadeiras ao diretório que contém as fontes de imagens originais, independentemente codificação da imagem original, essa tarefa produzirá um WebP eficiente e um substituto de JPEG progressivo confiável e com nível de compressão que pode ser facilmente ajustado instantaneamente. É claro que esse processo também garante que a imagem original arquivos serão retidos no ambiente de desenvolvimento do projeto, o que significa que essas configurações podem ser ajustadas a qualquer momento com apenas a saída automatizada substituída.

Para gerar vários arquivos, você transmite vários objetos de configuração, todos iguais, exceto a adição de uma chave width e um valor em pixels:

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/'));
}

No caso do exemplo acima, a imagem original (monarch.png) tinha mais de 3,3 MB. O maior arquivo gerado pelo esta tarefa (monarch-1000.jpeg) tem aproximadamente 150 KB. O menor, monarch-400.web, tem apenas 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

É claro que você deve examinar cuidadosamente os resultados em busca de artefatos de compactação visíveis ou, possivelmente, aumentar a compactação para economizar mais. Como essa tarefa não é destrutiva, essas configurações podem ser alteradas facilmente.

No geral, em troca dos poucos kilobytes que você poderia eliminar com uma micro-otimização manual cuidadosa, você obtém um processo eficiente e resiliente: uma ferramenta que aplica perfeitamente seu conhecimento sobre recursos de imagem de alto desempenho. a um projeto inteiro, sem qualquer intervenção manual.

Marcação de imagem responsiva na prática

Preencher os atributos srcset normalmente é um processo manual simples, porque o atributo realmente só captura informações sobre a configuração que você já fez ao gerar as origens. Nas tarefas acima, estabelecemos os nomes de arquivos e as informações de largura que nosso atributo seguirá:

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

O conteúdo do atributo srcset é descritivo, não prescritivo. Não há problema em sobrecarregar um srcset, desde que a proporção de cada fonte seja consistente. Um atributo srcset pode conter o URI largura de cada corte alternativo gerado pelo servidor sem causar solicitações desnecessárias e quanto mais fontes fornecidas para uma imagem renderizada, mais eficiente será o navegador adaptar as solicitações.

Como você aprendeu em Imagens responsivas, convém usar o elemento <picture> para processar o WebP sem problemas. ou JPEG. Nesse caso, você vai usar o atributo type em conjunto com 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 você aprendeu, os navegadores com suporte a WebP vão reconhecer o conteúdo do atributo type e selecionar <source> o atributo srcset do elemento como a lista de candidatos de imagem. Navegadores que não reconhecem image/webp como uma mídia válida vai ignorar esse <source> e usar o atributo srcset do elemento interno <img>.

Há mais uma consideração em termos de suporte a navegadores: os navegadores sem suporte para marcações de imagem responsiva só ainda precisam de um substituto, ou podemos correr o risco de ter uma imagem corrompida em contextos de navegação especialmente antigos. Devido a <picture>, <source> e srcset são ignorados nesses navegadores, vamos especificar uma origem padrão no <img> interno. src.

Como o dimensionamento de uma imagem para baixo é visualmente contínuo e a codificação JPEG é universal, o maior JPEG é uma boa escolha.

<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>

Pode ser um pouco mais difícil lidar com sizes. Como você já aprendeu, sizes é necessariamente contextual. não pode preencher o atributo sem saber a quantidade de espaço que a imagem deve ocupar no layout renderizado. Para solicitações mais eficientes, um atributo sizes preciso precisa estar na nossa marcação no momento em que essas solicitações forem feitas são feitas pelo usuário final, muito antes de os estilos que regem o layout da página serem solicitados. Omitir totalmente sizes não é apenas uma violação da especificação HTML, mas resulta em um comportamento padrão equivalente ao sizes="100vw", informando no navegador que essa imagem seja restrita apenas pela própria janela de visualização, resultando nas maiores origens possíveis de candidatos; que está sendo selecionado.

Como acontece com qualquer tarefa de desenvolvimento web particularmente trabalhosa, diversas ferramentas foram criadas para abstrairem-se o processo de escrever à mão atributos sizes. respImageLint é totalmente snippet essencial de código destinado a verificar a precisão dos atributos sizes e fornecer sugestões de melhoria. Ele é executado como um favorito, uma ferramenta que você executa no seu navegador, enquanto aponta para a página totalmente renderizada que contém sua imagem. os elementos. Em um contexto em que o navegador tenha compreensão completa do layout da página, ele também terá uma visualização praticamente perfeita reconhecimento do espaço que uma imagem deve ocupar nesse layout em todos os tamanhos de janela de visualização possíveis.

Relatório de imagens responsivas mostrando incompatibilidade de tamanho/largura.

Uma ferramenta para inspecionar seus atributos sizes certamente é útil, mas tem ainda mais valor como uma ferramenta para gerá-los em grande escala. Como você sabe, a sintaxe srcset e sizes tem como objetivo otimizar as solicitações de recursos de imagem de uma maneira visualmente perfeita. Embora não deve ser usado em produção, um valor padrão do marcador sizes padrão de 100vw é perfeitamente razoável ao trabalhar no layout de uma página em seu ambiente de desenvolvimento local. Quando os estilos de layout estiverem prontos, executar respImageLint fornecerá atributos sizes personalizados, que você poderá copiar e colar em sua marcação, com um nível de detalhe muito maior do que uma escrita à mão:

Relatório de imagens responsivas com dimensões sugeridas.

Embora as solicitações de imagem iniciadas por marcação renderizada pelo servidor aconteçam muito rapidamente para o JavaScript gerar um atributo sizes do lado do cliente, o mesmo raciocínio não se aplica quando essas solicitações são iniciadas no lado do cliente. O projeto Lazysizes por exemplo, permite adiar totalmente solicitações de imagem até que o layout tenha sido estabelecido, permitindo que o JavaScript gere nossos valores de sizes para nós: uma grande conveniência para você e uma garantia de solicitações mais eficientes para seus usuários. No entanto, essa abordagem significa sacrificar a confiabilidade da marcação renderizada pelo servidor e a velocidade em navegadores, e iniciar essas solicitações somente após a renderização da página causará uma impacto negativo na sua pontuação de LCP.

É claro que se você já depende de um framework de renderização do lado do cliente, como React ou Vue, não tem problema. serão incorridos. Nesses casos, usar Lazysizes significa que os atributos sizes podem ser quase completamente abstraídos. Melhor ainda: já que sizes="auto" em imagens de carregamento lento ganha consenso e implementações nativas, o Lazysizes vai se tornar efetivamente um polyfill para o comportamento recém-padronizado do navegador.