Carregamento lento de imagens e elementos <iframe>

Imagens e elementos <iframe> geralmente consomem mais largura de banda do que outros tipos de recursos. No caso de elementos <iframe>, uma quantidade razoável de tempo de processamento extra pode estar envolvida no carregamento e na renderização das páginas neles.

No caso do carregamento lento de imagens, adiar o carregamento de imagens fora da janela de visualização inicial pode ser útil para reduzir a contenção de largura de banda de recursos mais importantes na janela de visualização inicial. Isso pode melhorar a Maior exibição de conteúdo (LCP) de uma página em alguns casos em que as conexões de rede são ruins, e essa largura de banda realocada pode ajudar os candidatos de LCP a carregar e exibir mais rapidamente.

No caso dos elementos <iframe>, a Interaction to Next Paint (INP) de uma página pode ser melhorada durante a inicialização com o carregamento lento. Isso ocorre porque um <iframe> é um documento HTML completamente separado com os próprios subrecursos. Embora os elementos <iframe> possam ser executados em um processo separado, não é incomum que eles compartilhem um processo com outras linhas de execução, o que pode criar condições em que as páginas se tornam menos responsivas à entrada do usuário.

Portanto, adiar o carregamento de imagens fora da tela e elementos <iframe> é uma técnica que vale a pena seguir e requer um esforço bastante baixo para um retorno razoavelmente bom em termos de desempenho. Este módulo explica como carregar esses dois tipos de elementos de forma lazy load para uma experiência do usuário mais rápida e melhor durante o período crítico de inicialização da página.

Carregar imagens com o atributo loading

O atributo loading pode ser adicionado a elementos <img> para informar aos navegadores como eles devem ser carregados:

  • "eager" informa ao navegador que a imagem precisa ser carregada imediatamente, mesmo que esteja fora da viewport inicial. Esse também é o valor padrão do atributo loading.
  • "lazy" adia o carregamento de uma imagem até que ela esteja a uma distância definida da janela de visualização visível. Essa distância varia de acordo com o navegador, mas geralmente é definida de forma que a imagem seja carregada quando o usuário rola a tela até ela.

Também é importante observar que, se você estiver usando o elemento <picture>, o atributo loading ainda precisará ser aplicado ao elemento filho <img>, não ao elemento <picture>. Isso ocorre porque o elemento <picture> é um contêiner que contém outros elementos <source> que apontam para diferentes candidatos de imagem, e o candidato escolhido pelo navegador é aplicado diretamente ao elemento filho <img>.

Não carregar imagens com carregamento lento que estão na janela de visualização inicial

Só adicione o atributo loading="lazy" a elementos <img> posicionados fora da janela de visualização inicial. No entanto, pode ser complexo saber a posição precisa de um elemento relativo dentro da viewport antes que a página seja renderizada. É preciso considerar diferentes tamanhos de janela de visualização, proporções e dispositivos.

Por exemplo, uma janela de visualização de desktop pode ser bastante diferente de uma janela de visualização em um smartphone, porque renderiza mais espaço vertical, o que pode fazer com que imagens sejam ajustadas na janela de visualização inicial que não apareceriam na janela de visualização inicial de um dispositivo fisicamente menor. Os tablets usados na orientação retrato também mostram uma quantidade considerável de espaço vertical, talvez até mais do que alguns dispositivos de mesa.

No entanto, há alguns casos em que é bastante claro que você precisa evitar aplicar loading="lazy". Por exemplo, omita o atributo loading="lazy" dos elementos <img> em casos de imagens principais ou outros casos de uso de imagem em que os elementos <img> provavelmente aparecem acima da dobra ou perto da parte de cima do layout em qualquer dispositivo. Isso é ainda mais importante para imagens que provavelmente serão candidatas a LCP.

As imagens carregadas de forma lenta precisam esperar que o navegador conclua o layout para saber se a posição final da imagem está dentro da viewport. Isso significa que, se um elemento <img> na viewport visível tiver um atributo loading="lazy", ele só será solicitado depois de todo o CSS ser transferido por download, analisado e aplicado à página, em vez de ser buscado assim que for descoberto pelo leitor de pré-carregamento na marcação bruta.

Como o atributo loading no elemento <img> tem suporte em todos os principais navegadores, não é necessário usar JavaScript para carregar imagens de forma lenta, já que adicionar JavaScript extra a uma página para fornecer recursos que o navegador já oferece afeta outros aspectos do desempenho da página, como o INP.

Demonstração de carregamento lento de imagens

Carregar elementos <iframe> com carregamento lento

O carregamento lento de elementos <iframe> até que eles fiquem visíveis na viewport pode economizar dados significativos e melhorar o carregamento de recursos importantes que são necessários para carregar a página de nível superior. Além disso, como os elementos <iframe> são essencialmente documentos HTML inteiros carregados em um documento de nível superior, eles podem incluir um número significativo de subrecursos, principalmente JavaScript, que podem afetar consideravelmente o INP de uma página se as tarefas nesses frames exigirem tempo de processamento significativo.

As incorporações de terceiros são um caso de uso comum para elementos <iframe>. Por exemplo, players de vídeo incorporados ou postagens em mídias sociais geralmente usam elementos <iframe> e muitas vezes exigem um número significativo de subrecursos, o que também pode resultar em disputa de largura de banda para os recursos da página de nível superior. Por exemplo, o carregamento lento de uma incorporação de vídeo do YouTube economiza mais de 500 KiB durante o carregamento inicial da página, enquanto o carregamento lento do plug-in do botão "Gostei" do Facebook economizou mais de 200 KiB, a maioria deles em JavaScript.

De qualquer forma, sempre que você tiver um <iframe> abaixo da dobra em uma página, considere o carregamento lento se não for essencial carregá-lo na parte da frente, porque isso pode melhorar significativamente a experiência do usuário.

O atributo loading para elementos <iframe>

O atributo loading em elementos <iframe> também tem suporte em todos os principais navegadores. Os valores do atributo loading e o comportamento deles são os mesmos dos elementos <img> que usam o atributo loading:

  • "eager" é o valor padrão. Ele informa ao navegador para carregar o HTML do elemento <iframe> e os subrecursos dele imediatamente.
  • O "lazy" adia o carregamento do HTML do elemento <iframe> e dos subrecursos até que ele esteja dentro de uma distância predefinida da janela de visualização.

Demonstração de iframes com carregamento lento

Fachadas

Em vez de carregar uma incorporação imediatamente durante o carregamento da página, você pode fazer isso sob demanda em resposta a uma interação do usuário. Isso pode ser feito mostrando uma imagem ou outro elemento HTML apropriado até que o usuário interaja com ele. Quando o usuário interagir com o elemento, você poderá substituí-lo pela incorporação de terceiros. Essa técnica é conhecida como façata.

Um caso de uso comum para fachadas é a incorporação de vídeos de serviços de terceiros, em que a incorporação pode envolver o carregamento de muitos subrecursos adicionais e potencialmente caros, como JavaScript, além do conteúdo do vídeo. Nesse caso, a menos que haja uma necessidade legítima de um vídeo ser reproduzido automaticamente, as incorporações de vídeo exigem que o usuário interaja com elas antes da reprodução, clicando no botão de reprodução.

Essa é uma ótima oportunidade para mostrar uma imagem estática visualmente semelhante à incorporação do vídeo e economizar largura de banda significativa no processo. Quando o usuário clicar na imagem, ela será substituída pela incorporação <iframe> real, que aciona o HTML do elemento <iframe> de terceiros e os subrecursos para começar o download.

Além de melhorar o carregamento inicial da página, outra vantagem importante é que, se o usuário não reproduzir o vídeo, os recursos necessários para o envio não serão transferidos. Esse é um bom padrão, porque garante que o usuário só faça o download do que ele realmente quer, sem fazer suposições erradas sobre as necessidades do usuário.

Os widgets de chat são outro excelente caso de uso para a técnica de fachada. A maioria dos widgets de chat faz o download de quantidades significativas de JavaScript que podem afetar negativamente o carregamento da página e a capacidade de resposta à entrada do usuário. Assim como ao carregar qualquer coisa na parte frontal, o custo é incorrido no momento do carregamento, mas, no caso de um widget de chat, nem todos os usuários têm a intenção de interagir com ele.

Com uma fachada, é possível substituir o botão "Iniciar chat" de terceiros por um botão falso. Quando o usuário interage de forma significativa com ele, como ao manter o ponteiro sobre ele por um período razoável ou com um clique, o widget de chat funcional é colocado no lugar quando o usuário precisa dele.

É possível criar suas próprias fachadas, mas há opções de código aberto disponíveis para terceiros mais conhecidos, como lite-youtube-embed para vídeos do YouTube, lite-vimeo-embed para vídeos do Vimeo e React Live Chat Loader para widgets de chat.

Bibliotecas de carregamento lento do JavaScript

Se você precisar fazer o carregamento lento de elementos <video>, imagens poster do elemento <video>, imagens carregadas pela propriedade background-image do CSS ou outros elementos sem suporte, faça isso com uma solução de carregamento lento baseada em JavaScript, como lazysizes ou yall.js, já que o carregamento lento desses tipos de recursos não é um recurso do navegador.

Em particular, a reprodução automática e a repetição de elementos <video> sem uma faixa de áudio são uma alternativa muito mais eficiente do que o uso de GIFs animados, que podem ser muitas vezes maiores do que um recurso de vídeo de qualidade visual equivalente. Mesmo assim, esses vídeos ainda podem ser significativos em termos de largura de banda. Portanto, o carregamento lento é uma otimização adicional que pode ajudar muito a reduzir o desperdício de largura de banda.

A maioria dessas bibliotecas funciona usando a API Intersection Observer e, além disso, a API Mutation Observer, se o HTML de uma página mudar após o carregamento inicial, para reconhecer quando um elemento entra na viewport do usuário. Se a imagem estiver visível ou se estiver se aproximando da viewport, a biblioteca JavaScript substituirá o atributo não padrão (geralmente data-src ou um atributo semelhante) pelo atributo correto, como src.

Digamos que você tenha um vídeo que substitui um GIF animado, mas queira fazer o carregamento lento com uma solução JavaScript. Isso é possível com o yall.js com o seguinte padrão de marcação:

<!-- The autoplay, loop, muted, and playsinline attributes are to
     ensure the video can autoplay without user intervention. -->
<video class="lazy" autoplay loop muted playsinline width="320" height="480">
  <source data-src="video.webm" type="video/webm">
  <source data-src="video.mp4" type="video/mp4">
</video>

Por padrão, o yall.js observa todos os elementos HTML qualificados com uma classe de "lazy". Depois que o yall.js for carregado e executado na página, o vídeo não será carregado até que o usuário role para a janela de visualização. Nesse ponto, os atributos data-src nos elementos <source> filhos do elemento <video> são trocados por atributos src, que enviam uma solicitação para fazer o download do vídeo e iniciar a reprodução automaticamente.

Teste seus conhecimentos

Qual é o valor padrão do atributo loading para os elementos <img> e <iframe>?

"eager"
Correto.
"lazy"
Tente novamente.

Quando é razoável usar soluções de carregamento lento com base em JavaScript?

Para qualquer recurso que possa ser carregado lentamente.
Tente novamente.
Para recursos em que o atributo loading não tem suporte, como no caso de vídeos de reprodução automática destinados a substituir imagens animadas ou para carregar de forma lenta a imagem do pôster de um elemento <video>.
Correto.

Quando uma fachada é uma técnica útil?

Para qualquer incorporação de terceiros que consuma dados significativos, independentemente das necessidades do usuário.
Tente novamente.
Para qualquer incorporação de terceiros em que os recursos necessários para o carregamento não sejam apenas substanciais, mas haja uma probabilidade razoável de que nem todos os usuários possam interagir com eles.
Correto.

Próximo: pré-busca e pré-renderização

Agora que você sabe como carregar imagens e elementos <iframe> de forma lenta, você está em uma boa posição para garantir que as páginas sejam carregadas mais rapidamente, respeitando as necessidades dos usuários. No entanto, há casos em que o carregamento especulativo de recursos pode ser desejável. No próximo módulo, aprenda sobre a pré-busca e a pré-renderização e como essas técnicas, quando usadas com cuidado, podem acelerar substancialmente a navegação para páginas subsequentes, carregando-as com antecedência.