As imagens costumam ser o recurso mais pesado e mais comum na Web. Por isso, otimizar imagens pode melhorar significativamente a performance do seu site. Na maioria dos casos, otimizar imagens significa reduzir o tempo de rede enviando menos bytes, mas também é possível otimizar a quantidade de bytes enviados ao usuário veiculando imagens dimensionadas corretamente para o dispositivo dele.
As imagens podem ser adicionadas a uma página usando os elementos <img> ou <picture> ou
a propriedade background-image do CSS.
Tamanho da imagem
A primeira otimização que você pode fazer ao usar recursos de imagem é mostrar a imagem no tamanho correto. Nesse caso, o termo tamanho se refere às dimensões de uma imagem. Considerando que não há outras variáveis, uma imagem exibida em um contêiner de 500 pixels por 500 pixels teria o tamanho ideal de 500 pixels por 500 pixels. Por exemplo, usar uma imagem quadrada de 1.000 pixels significa que ela é duas vezes maior do que o necessário.
No entanto, há muitas variáveis envolvidas na escolha do tamanho adequado da imagem, o que torna a tarefa de escolher o tamanho adequado em todos os casos bastante complicada. Em 2010, quando o iPhone 4 foi lançado, a resolução da tela (640 x 960) era o dobro da do iPhone 3 (320 x 480). No entanto, o tamanho físico da tela do iPhone 4 permaneceu aproximadamente o mesmo do iPhone 3.
Mostrar tudo na resolução mais alta teria diminuído significativamente o texto e as imagens, exatamente pela metade do tamanho anterior. Em vez disso, um pixel se tornou dois pixels do dispositivo. Isso é chamado de proporção de pixels do dispositivo (DPR). O iPhone 4 (e muitos modelos lançados depois) tinha um DPR de 2.
Retomando o exemplo anterior, se o dispositivo tiver uma DPR de 2 e a imagem for exibida em um contêiner de 500 pixels por 500 pixels, uma imagem quadrada de 1.000 pixels (chamada de tamanho intrínseco) será o tamanho ideal. Da mesma forma, se o dispositivo tiver um DPR de 3, uma imagem quadrada de 1.500 pixels será o tamanho ideal.
Você pode usar uma imagem menor do que o tamanho ideal sem uma diminuição perceptível na qualidade da imagem para a maioria dos usuários.srcset
O elemento <img> é compatível com o atributo srcset, que permite especificar uma
lista de possíveis origens de imagem que o navegador pode usar. Cada origem de imagem especificada precisa incluir o URL da imagem e um descritor de densidade de pixels de largura ou.
<img
alt="An image"
width="500"
height="500"
src="/image-500.jpg"
srcset="/image-500.jpg 1x, /image-1000.jpg 2x, /image-1500.jpg 3x"
>
O snippet HTML anterior usa o descritor de densidade de pixels para sugerir ao navegador
que use image-500.png em dispositivos com um DPR de 1, image-1000.jpg em dispositivos
com um DPR de 2 e image-1500.jpg em dispositivos com um DPR de 3.
Embora tudo isso possa parecer simples, a DPR de uma tela não é a única consideração ao escolher a imagem ideal para uma determinada página. O layout da página é outra consideração.
sizes
A solução anterior só funciona se você mostrar a imagem no mesmo tamanho de pixel CSS em todas as janelas de visualização. Em muitos casos, o layout de uma página e o tamanho do contêiner mudam dependendo do dispositivo do usuário.
Com o atributo sizes, é possível especificar um conjunto de tamanhos de origem, em que cada
tamanho consiste em uma condição de mídia e um valor. O atributo sizes descreve o tamanho de exibição pretendido da imagem em pixels CSS. Quando combinados
com os descritores de largura srcset, o navegador pode escolher qual origem de imagem
é a melhor para o dispositivo do usuário.
<img
alt="An image"
width="500"
height="500"
src="/image-500.jpg"
srcset="/image-500.jpg 500w, /image-1000.jpg 1000w, /image-1500.jpg 1500w"
sizes="(min-width: 768px) 500px, 100vw"
>
No snippet HTML anterior, o atributo srcset especifica uma lista de candidatos a imagens que o navegador pode escolher, separados por vírgulas. Cada candidato na lista consiste no URL da imagem, seguido por uma sintaxe que denota a largura intrínseca da imagem. O tamanho intrínseco de uma imagem são as dimensões dela. Por exemplo, um descritor de 1000w indica que a largura intrínseca da imagem é de 1.000 pixels.
Com essas informações, o navegador avalia a condição de mídia no atributo sizes e, nesse caso, recebe a instrução de que, se a largura da janela de visualização do dispositivo exceder 768 pixels, a imagem será mostrada com uma largura de 500 pixels. Em dispositivos menores, a imagem é exibida em 100vw ou na largura total da janela de visualização.
Em seguida, o navegador pode combinar essas informações com a lista de fontes de imagens srcset para encontrar a imagem ideal. Por exemplo, se o usuário estiver em um dispositivo móvel
com uma largura de tela de 320 pixels e um DPR de 3, a imagem será mostrada
em 320 CSS pixels x 3 DPR = 960 device pixels. Neste exemplo, a imagem de tamanho mais próximo seria image-1000.jpg, que tem uma largura intrínseca de 1.000 pixels (1000w).
Formatos de arquivo
Os navegadores são compatíveis com vários formatos de arquivo de imagem diferentes. Formatos de imagem modernos, como WebP e AVIF, podem oferecer uma compactação melhor do que PNG ou JPEG, reduzindo o tamanho do arquivo de imagem e, portanto, levando menos tempo para fazer o download. Ao veicular imagens em formatos modernos, você pode reduzir o tempo de carregamento de um recurso, o que pode resultar em uma Maior exibição de conteúdo (LCP) menor.
O WebP é um formato amplamente aceito que funciona em todos os navegadores modernos. O WebP geralmente tem uma compactação melhor do que JPEG, PNG ou GIF, oferecendo com perda e sem perda. O WebP também é compatível com transparência do canal Alfa, mesmo ao usar compactação com perda, um recurso que o codec JPEG não oferece.
O AVIF é um formato de imagem mais recente e, embora não seja tão amplamente aceito quanto o WebP, ele tem suporte razoavelmente bom em todos os navegadores. O AVIF é compatível com compactação com e sem perda, e testes mostraram uma economia de mais de 50% em comparação com o JPEG em alguns casos. O AVIF também oferece recursos de ampla gama de cores (WCG) e intervalo dinâmico alto (HDR).
Compactação
Em relação às imagens, há dois tipos de compactação:
A compactação com perda reduz a acurácia da imagem por quantização, e outras informações de cor podem ser descartadas usando subamostragem de croma. A compactação com perdas é mais eficaz em imagens de alta densidade com muito ruído e cores, geralmente fotos ou imagens com conteúdo semelhante. Isso acontece porque os artefatos produzidos pela compactação com perdas têm muito menos chances de serem notados em imagens tão detalhadas. No entanto, a compactação com perdas pode ser menos eficaz com imagens que contêm bordas nítidas, como arte linear, detalhes igualmente nítidos ou texto. A compactação com perda pode ser aplicada a imagens JPEG, WebP e AVIF.
A compactação sem perdas reduz o tamanho do arquivo compactando uma imagem sem perda de dados. A compactação sem perdas descreve um pixel com base na diferença dos pixels vizinhos. A compactação sem perda é usada para os formatos de imagem GIF, PNG, WebP e AVIF.
É possível compactar as imagens usando o Squoosh, o ImageOptim ou um serviço de otimização de imagens. Ao compactar, não há uma configuração universal adequada para todos os casos. A abordagem recomendada é testar diferentes níveis de compactação até encontrar um bom compromisso entre qualidade da imagem e tamanho do arquivo. Alguns serviços avançados de otimização de imagens fazem isso automaticamente, mas podem não ser viáveis financeiramente para todos os usuários.
O elemento <picture>
O elemento <picture> oferece mais flexibilidade na especificação de vários candidatos a imagem:
<picture>
<source type="image/avif" srcset="image.avif">
<source type="image/webp" srcset="image.webp">
<img
alt="An image"
width="500"
height="500"
src="/image.jpg">
</picture>
Ao usar elementos <source> no elemento <picture>, é possível adicionar suporte a imagens AVIF e WebP, mas voltar a formatos de imagem legados mais compatíveis se o navegador não for compatível com formatos modernos. Com essa abordagem, o navegador escolhe o primeiro elemento <source> especificado que corresponde. Se for possível renderizar a imagem nesse formato, ela será usada. Caso contrário, o navegador
passa para o próximo elemento <source> especificado. No snippet HTML anterior, o formato AVIF tem prioridade sobre o WebP, voltando para o JPEG se nenhum dos dois for compatível.
Um elemento <picture> exige um elemento <img> aninhado dentro dele. Os atributos alt, width e height são definidos no <img> e usados
independente de qual <source> é selecionado.
O elemento <source> também é compatível com os atributos media, srcset e sizes. Assim como no exemplo de <img>, eles indicam ao
navegador qual imagem selecionar em diferentes viewports.
<picture>
<source
media="(min-resolution: 1.5x)"
srcset="/image-1000.jpg 1000w, /image-1500.jpg 1500w"
sizes="(min-width: 768px) 500px, 100vw">
<img
alt="An image"
width="500"
height="500"
src="/image-500.jpg">
</picture>
O atributo media usa uma condição de mídia. No exemplo anterior, o DPR do dispositivo é usado como a condição de mídia. Qualquer dispositivo com um DPR maior ou igual a 1,5 usaria o primeiro elemento <source>. O elemento <source>
informa ao navegador que, em dispositivos com uma janela de visualização maior que 768 pixels, a
imagem candidata selecionada é mostrada com 500 pixels de largura. Em dispositivos menores,
isso ocupa toda a largura da janela de visualização. Ao combinar os atributos media e srcset, você tem um controle mais refinado sobre qual imagem usar.
Isso é ilustrado na tabela a seguir, em que várias larguras de viewport e proporções de pixels do dispositivo são avaliadas:
| Largura da janela de visualização (pixels) | 1 DPR | 1,5 DPR | 2 DPR | 3 DPR |
|---|---|---|---|---|
| 320 | 500.jpg | 500.jpg | 500.jpg | 1000.jpg |
| 480 | 500.jpg | 500.jpg | 1000.jpg | 1500.jpg |
| 560 | 500.jpg | 1000.jpg | 1000.jpg | 1500.jpg |
| 1024 | 500.jpg | 1000.jpg | 1000.jpg | 1500.jpg |
| 1920 | 500.jpg | 1000.jpg | 1000.jpg | 1500.jpg |
Dispositivos com um DPR de 1 baixam a imagem image-500.jpg, incluindo a maioria dos usuários de computadores, que veem a imagem em um tamanho extrínseco de 500 pixels de largura. Por outro lado, usuários de dispositivos móveis com um DPR de 3 baixam um image-1500.jpg potencialmente maior, a mesma imagem usada em dispositivos desktop com um DPR de 3.
<picture>
<source
media="(min-width: 561px) and (min-resolution: 1.5x)"
srcset="/image-1000.jpg 1000w, /image-1500.jpg 1500w"
sizes="(min-width: 768px) 500px, 100vw">
<source
media="(max-width: 560px) and (min-resolution: 1.5x)"
srcset="/image-1000-sm.jpg 1000w, /image-1500-sm.jpg 1500w"
sizes="(min-width: 768px) 500px, 100vw">
<img
alt="An image"
width="500"
height="500"
src="/image-500.jpg">
</picture>
Neste exemplo, o elemento <picture> é ajustado para incluir um elemento <source> adicional e usar imagens diferentes para dispositivos largos com um DPR alto:
| Largura da janela de visualização (pixels) | 1 DPR | 1,5 DPR | 2 DPR | 3 DPR |
|---|---|---|---|---|
| 320 | 500.jpg | 500.jpg | 1000-sm.jpg | 1000-sm.jpg |
| 480 | 500.jpg | 500.jpg | 1000-sm.jpg | 1500-sm.jpg |
| 560 | 500.jpg | 1000-sm.jpg | 1000-sm.jpg | 1500-sm.jpg |
| 1024 | 500.jpg | 1000.jpg | 1000.jpg | 1500.jpg |
| 1920 | 500.jpg | 1000.jpg | 1000.jpg | 1500.jpg |
Com essa consulta adicional, você pode ver que image-1000-sm.jpg e image-1500-sm.jpg são mostrados em pequenas janelas de visualização. Essas informações extras
permitem compactar ainda mais as imagens, já que os artefatos de compactação não são muito
visíveis nesse tamanho e densidade, sem comprometer a qualidade da imagem
em dispositivos desktop.
Como alternativa, ajuste os atributos srcset e media para evitar veicular imagens grandes em janelas de visualização pequenas:
<picture>
<source
media="(min-width: 561px)"
srcset="/image-500.jpg, /image-1000.jpg 2x, /image-1500.jpg 3x">
<source
media="(max-width: 560px)"
srcset="/image-500.jpg 1x, /image-1000.jpg 2x">
<img
alt="An image"
width="500"
height="500"
src="/image-500.jpg">
</picture>
No snippet de HTML anterior, os descritores de largura foram removidos em favor dos descritores de proporção de pixels do dispositivo. As imagens veiculadas em um dispositivo móvel são limitadas a /image-500.jpg ou /image-1000.jpg, mesmo em dispositivos com um DPR de 3.
Gerenciar complexidade
Ao trabalhar com imagens responsivas, você pode ter muitas variações de tamanho e formatos diferentes para cada imagem. No exemplo anterior, as variações para cada tamanho são usadas, mas excluem AVIF e WebP. Quantas variantes você deve ter? Como muitos problemas de engenharia, a resposta tende a ser "depende".
Embora seja tentador ter o máximo de variações para oferecer a melhor opção, cada variante de imagem adicional tem um custo e torna o uso do cache do navegador menos eficiente. Com apenas uma variante, todos os usuários recebem a mesma imagem, que pode ser armazenada em cache de maneira muito eficiente.
Por outro lado, se houver muitas variações, cada uma delas vai exigir outra entrada de cache. Os custos do servidor podem aumentar e prejudicar o desempenho se a entrada de cache da variante expirar e a imagem precisar ser buscada novamente no servidor de origem.
Além disso, o tamanho do documento HTML aumenta a cada variação. Você pode acabar enviando vários kilobytes de HTML para cada imagem.
Veicular imagens com base no cabeçalho da solicitação Accept
O cabeçalho de solicitação HTTP Accept informa ao servidor quais tipos de conteúdo o navegador do usuário entende. Essas informações podem ser usadas pelo seu servidor para veicular
o formato de imagem ideal sem adicionar bytes extras às suas respostas HTML.
if (request.headers.accept) {
if (request.headers.accept.includes('image/avif')) {
return reply.from('image.avif');
} else if (request.headers.accept.includes('image/webp')) {
return reply.from('image.webp');
}
}
return reply.from('image.jpg');
O snippet de HTML anterior é uma versão simplificada do código que pode ser adicionado ao
back-end JavaScript do servidor para escolher e veicular o formato de imagem ideal.
Se o cabeçalho da solicitação Accept incluir image/avif, a imagem AVIF será
fornecida. Caso contrário, se o cabeçalho Accept incluir image/webp, a imagem WebP será veiculada. Se nenhuma dessas condições for verdadeira, a imagem JPEG será
fornecida.
É possível modificar as respostas com base no conteúdo do cabeçalho de solicitação Accept em quase todos os tipos de servidores da Web. Por exemplo, é possível reescrever solicitações de imagens
em servidores Apache com base no cabeçalho Accept usando mod_rewrite.
Isso não é diferente do comportamento que você encontraria em uma rede de fornecimento de conteúdo (CDN) de imagens. As CDNs de imagens são excelentes soluções para otimizar imagens e enviar o formato ideal com base no dispositivo e no navegador do usuário.
O ideal é encontrar um equilíbrio, gerar um número razoável de candidatos de imagem e medir o impacto na experiência do usuário. Imagens diferentes podem gerar resultados diferentes, e as otimizações aplicadas a cada uma delas dependem do tamanho na página e dos dispositivos usados pelos usuários. Por exemplo, uma imagem principal de largura total pode exigir mais variantes do que miniaturas em uma página de listagem de produtos de e-commerce.
Carregamento lento
É possível instruir o navegador a carregar imagens de forma lenta quando elas aparecem na
janela de visualização usando o atributo loading. Um valor de atributo lazy informa ao
navegador para não baixar a imagem até que ela esteja na (ou perto da) janela de visualização. Isso economiza largura de banda, permitindo que o navegador priorize os recursos necessários para renderizar o conteúdo essencial que já está na janela de visualização.
Atributo de decodificação
O atributo decoding informa ao navegador como decodificar a imagem.
Há três valores possíveis:
asyncinforma ao navegador que a imagem pode ser decodificada de forma assíncrona, o que pode melhorar o tempo de renderização de outros conteúdos.syncinforma ao navegador que a imagem deve ser apresentada ao mesmo tempo que outros conteúdos.- O
auto(padrão) permite que o navegador decida o que é melhor para o usuário.
É possível usar o método decode em uma instância de um HTMLImageElement em JavaScript ao inserir uma imagem no DOM.
Demonstração de imagem
Teste seus conhecimentos
Quais formatos de imagem são compatíveis com a compactação sem perda?
Quais formatos de imagem são compatíveis com a compactação com perda?
O que o descritor de largura (por exemplo, 1000w) informa ao navegador sobre uma opção de imagem especificada em um atributo srcset?
O que o atributo sizes informa ao navegador sobre um elemento
<img> a que ele é aplicado?
<img> elemento srcset deve ser carregado,
considerando as dimensões da janela de visualização atual do usuário.
srcset do elemento
<img>.
Próximo: performance do vídeo
Embora as imagens sejam o tipo de mídia mais comum usado na Web, elas não são o único que você precisa considerar quando se trata de desempenho. O vídeo é outro tipo comum de mídia usado na Web e tem considerações de performance próprias. No próximo módulo deste curso, vamos explorar algumas técnicas para otimizar vídeos e carregá-los com eficiência.