Pré-carregamento de imagens responsivas

A partir do Chrome 73, link rel="preload" e imagens responsivas podem ser combinados para carregar imagens mais rapidamente.

Compatibilidade com navegadores

  • 73
  • 79
  • 78
  • 17,2

Este artigo me dá a oportunidade de discutir dois dos meus assuntos favoritos: imagens responsivas e pré-carregamento. Como alguém estava muito envolvido no desenvolvimento desses dois recursos, estou muito animado com o trabalho deles juntos!

Visão geral das imagens responsivas

Suponha que você esteja navegando na Web em uma tela com 300 pixels de largura e que a página acabou de solicitar uma imagem de 1.500 pixels de largura. Essa página desperdiçava muitos dados da sua rede celular, porque sua tela não pode fazer nada com toda essa resolução extra. O ideal é que o navegador busque uma versão da imagem que seja um pouco mais larga do que o tamanho da tela, digamos, 325 pixels. Isso garante uma imagem de alta resolução sem desperdiçar dados. E o melhor: a imagem carrega mais rápido. As imagens responsivas permitem que os navegadores busquem diferentes recursos de imagem para diferentes dispositivos. Se você não usar uma CDN de imagem, será necessário salvar várias dimensões para cada imagem e especificá-las no atributo srcset. O valor w informa ao navegador a largura de cada versão. Dependendo do dispositivo, o navegador pode escolher a opção apropriada:

<img src="small.jpg" srcset="small.jpg 500w, medium.jpg 1000w, large.jpg 1500w" alt="…">

Visão geral do pré-carregamento

O pré-carregamento permite que você informe ao navegador sobre recursos críticos que deseja carregar o mais rápido possível, antes que sejam descobertos em HTML. Isso é especialmente útil para recursos que não são facilmente detectáveis, como fontes incluídas em folhas de estilo, imagens de plano de fundo ou recursos carregados de um script.

<link rel="preload" as="image" href="important.png">

Imagens responsivas + pré-carregamento = carregamentos de imagem mais rápidos

As imagens responsivas e o pré-carregamento estavam disponíveis nos últimos anos, mas, ao mesmo tempo, algo estava faltando: não havia como fazer o pré-carregamento de imagens responsivas. A partir do Chrome 73, o navegador pode pré-carregar a variante certa de imagens responsivas especificadas em srcset antes de descobrir a tag img.

Dependendo da estrutura do site, isso pode resultar em uma exibição de imagem significativamente mais rápida. Executamos testes em um site que usa JavaScript para carregar imagens responsivas lentamente. O pré-carregamento resultou em um carregamento de imagens 1,2 segundo mais rápido.

imagesrcset e imagesizes

Para pré-carregar imagens responsivas, novos atributos foram adicionados recentemente ao elemento <link>: imagesrcset e imagesizes. Elas são usadas com <link rel="preload"> e correspondem às sintaxes srcset e sizes usadas no elemento <img>.

Por exemplo, se você quiser pré-carregar uma imagem responsiva especificada com:

 <img src="wolf.jpg" srcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" sizes="50vw" alt="A rad wolf">

Para isso, adicione o seguinte ao <head> do HTML:

<link rel="preload" as="image" href="wolf.jpg" imagesrcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" imagesizes="50vw">

Isso inicia uma solicitação usando a mesma lógica de seleção de recursos que srcset e sizes vão aplicar.

Casos de uso

Pré-carregamento de imagens responsivas injetadas dinamicamente

Digamos que você esteja carregando dinamicamente imagens hero como parte de uma apresentação de slides e saiba qual imagem será exibida primeiro. Nesse caso, evite esperar o script antes de carregar a imagem em questão, já que isso atrasaria a exibição dela pelos usuários.

É possível inspecionar esse problema em um site com uma galeria de imagens carregada dinamicamente:

  1. Abra este site de exemplo em uma nova guia.

  2. Pressione "Control + Shift + J" (ou "Command + Option + J" no Mac) para abrir o DevTools.

  3. Clique na guia Rede.

  4. Na lista suspensa Limitação, selecione 3G rápido.

  5. Desmarque a caixa de seleção Desativar cache.

  6. Recarregue a página.

Captura de tela do painel &quot;Network&quot; do Chrome DevTools.
Essa hierarquia mostra que as imagens só começam a carregar depois que o navegador termina de executar o script, o que gera um atraso desnecessário no momento em que a imagem é exibida inicialmente para o usuário.

Usar preload ajuda aqui, porque a imagem começa a carregar antes do tempo e provavelmente já estará lá quando o navegador precisar mostrá-la.

Captura de tela do painel &quot;Network&quot; do Chrome DevTools.
Essa hierarquia mostra que a primeira imagem começou a ser carregada ao mesmo tempo que o script, evitando atrasos desnecessários e resultando em uma exibição mais rápida das imagens.

Para ver a diferença do pré-carregamento, inspecione a mesma galeria de imagens carregada dinamicamente, mas com a primeira imagem pré-carregada, seguindo as etapas do primeiro exemplo.

Pré-carregamento de imagens de plano de fundo usando o image-set

Se você tiver imagens de plano de fundo diferentes para densidades de tela diferentes, especifique-as no CSS com a sintaxe image-set. O navegador pode escolher qual exibir com base na DPR da tela.

background-image: image-set( "cat.png" 1x, "cat-2x.png" 2x);

O problema com imagens de plano de fundo CSS é que elas são descobertas pelo navegador somente depois de fazer o download e processar todo o CSS no <head> da página, que pode ser muito CSS...

Você pode inspecionar esse problema em um site de exemplo com uma imagem de plano de fundo responsiva.

Captura de tela do painel &quot;Network&quot; do Chrome DevTools.
Neste exemplo, o download da imagem não começa até que o CSS seja totalmente transferido, resultando em um atraso desnecessário para a exibição da imagem.

O pré-carregamento de imagem responsiva oferece uma maneira simples e sem riscos de carregar essas imagens mais rapidamente.

<link rel="preload" as="image" imagesrcset="cat.png 1x, cat-2x.png 2x">

Ao excluir o atributo href, você garante que os navegadores que não oferecem suporte a imagesrcset no elemento <link>, mas aceitam image-set no CSS, não farão o download de uma origem incorreta. No entanto, eles também não se beneficiarão do pré-carregamento nesse caso.

Você pode inspecionar como o exemplo anterior se comporta com uma imagem de plano de fundo responsiva pré-carregada.

Captura de tela do painel &quot;Network&quot; do Chrome DevTools.
Aqui o download da imagem e do CSS é iniciado ao mesmo tempo, evitando atrasos e resultando em um carregamento de imagem mais rápido.

Pré-carregamento de imagens responsivas em ação

O pré-carregamento de imagens responsivas pode acelerá-las na teoria, mas o que isso faz na prática?

Para responder que criei duas cópias de uma loja de PWA de demonstração: uma que não pré-carrega imagens e uma que pré-carrega algumas delas. Como o site faz o carregamento lento de imagens usando JavaScript, é provável que você se beneficie do pré-carregamento das que vão estar na janela de visualização inicial.

Isso me deu os seguintes resultados para sem pré-carregamento e para pré-carregamento de imagem. Analisando os números brutos, vemos que o Start Render permaneceu o mesmo, e o Speed Index melhorou um pouco (273 ms, porque as imagens chegam mais rápido, mas não ocupam uma grande parte da área do pixel), mas a métrica real que captura a diferença é a métrica Last Painted Hero, que melhorou em 1,2 segundo. 🎉🎉

Claro, nada captura a diferença visual como uma comparação de tira de filme:

Captura de tela da comparação de tiras de filme do WebPageTest mostrando que as imagens pré-carregadas são exibidas cerca de 1,5 segundo mais rápido.
A tira de filme mostra que as imagens chegam muito mais rápido quando pré-carregadas, resultando em uma experiência do usuário muito melhor.

Pré-carregar e <picture>?

Se você conhece as imagens responsivas, talvez esteja se perguntando: "E o <picture>?".

O grupo de trabalho de desempenho da Web quer adicionar um equivalente de pré-carregamento para srcset e sizes, mas não para o elemento <picture>, que lida com o caso de uso de "direção da arte".

Por que esse caso de uso está sendo "negligenciado"?

Também existe interesse em resolver esse caso de uso, mas ainda há vários problemas técnicos para resolver, o que significa que uma solução teria complexidade significativa. Além disso, parece que na maioria das vezes o caso de uso pode ser resolvido hoje, mesmo que de forma hackeada (veja abaixo).

Considerando isso, a WG de desempenho na Web decidiu enviar o srcset primeiro e verificar se surge a demanda por suporte equivalente ao picture.

Se você conseguir pré-carregar <picture>, poderá usar a técnica a seguir como solução alternativa.

Considere o seguinte cenário:

<picture>
    <source srcset="small_cat.jpg" media="(max-width: 400px)">
    <source srcset="medium_cat.jpg" media="(max-width: 800px)">
    <img src="large_cat.jpg">
</picture>

A lógica do elemento <picture>, ou lógica de seleção de origem da imagem, seria analisar os atributos media dos elementos <source> em ordem, encontrar o primeiro correspondente e usar o recurso anexado.

Como o pré-carregamento responsivo não tem noção de "ordem" ou "primeira correspondência", os pontos de interrupção precisam ser convertidos em algo como:

<link rel="preload" href="small_cat.jpg" as="image" media="(max-width: 400px)">
<link rel="preload" href="medium_cat.jpg" as="image" media="(min-width: 400.1px) and (max-width: 800px)">
<link rel="preload" href="large_cat.jpg" as="image" media="(min-width: 800.1px)">

Pré-carregamento e type

O elemento <picture> também oferece suporte à correspondência no primeiro type, para permitir que diferentes formatos de imagem sejam fornecidos e o navegador escolha o primeiro formato de imagem compatível. Este caso de uso não é compatível com o pré-carregamento no momento.

Para sites que usam isso, evitar o pré-carregamento é a melhor opção e, em vez disso, fazer com que o scanner de pré-carregamento as selecione usando os elementos <picture> e <source>. Essa é uma prática recomendada, principalmente com o suporte das Dicas de prioridade, que permitem priorizar melhor a imagem adequada do que usar apenas o pré-carregamento.

Efeitos na Maior exibição de conteúdo (LCP, na sigla em inglês)

Como as imagens podem ser candidatas à Maior exibição de conteúdo (LCP), o pré-carregamento pode melhorar a LCP do seu site. Usando as técnicas acima, você também pode garantir que suas imagens responsivas sejam carregadas mais rapidamente.

Independentemente de a imagem que você está pré-carregando ser responsiva, saiba que os pré-carregamentos funcionam especialmente bem quando o recurso de imagem não é detectável na carga de marcação inicial. Para sites que enviam marcação completa do servidor, você pode não perceber um grande benefício. No entanto, se o site renderiza marcação no cliente, o que substitui o verificador de pré-carregamento do navegador, há uma oportunidade de pré-carregar possíveis imagens de LCP para melhorar o desempenho.

Resumo

O pré-carregamento de imagem responsiva oferece possibilidades novas e empolgantes de pré-carregar imagens responsivas de maneiras que antes só eram possíveis usando truques. Essa é uma novidade importante que oferecemos aos desenvolvedores para garantir que as imagens importantes que queremos mostrar aos usuários o quanto antes estejam lá quando precisarmos delas.