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>, um tempo razoável de processamento extra pode ser envolvido no carregamento e na renderização das páginas dentro deles.

No caso de imagens de carregamento lento, adiar o carregamento de imagens que estão fora da janela de visualização inicial pode ajudar a reduzir a disputa de largura de banda para recursos mais importantes dentro da 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 a LCP a carregar e renderizar mais rápido.

No caso dos elementos <iframe>, o Interaction to Next Paint (INP) de uma página pode ser melhorado durante a inicialização com o carregamento lento. Isso acontece porque um <iframe> é um documento HTML completamente separado com seus próprios sub-recursos. 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 exige um esforço relativamente baixo para um retorno razoavelmente bom em termos de desempenho. Este módulo explica como fazer o carregamento lento desses dois tipos de elementos para uma experiência do usuário mais rápida e melhor durante o período de inicialização crítica da página.

Carregar imagens de forma lenta com o atributo loading

O loading atributo pode ser adicionado aos 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 janela de visualização inicial. Esse também é o valor padrão do atributo loading.
  • "lazy" adia o carregamento de uma imagem até que ela esteja a uma determinada distância da janela de visualização visível. Essa distância varia de acordo com o navegador, mas geralmente é definida como grande o suficiente para que a imagem seja carregada quando o usuário rolar até ela.

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

Não faça o carregamento lento de imagens na janela de visualização inicial

Só adicione o atributo loading="lazy" aos elementos <img> que estão posicionados fora da janela de visualização inicial. No entanto, pode ser complexo saber a posição exata de um elemento em relação à janela de visualização antes da renderização da página. É preciso considerar diferentes tamanhos de janela de visualização, proporções e dispositivos.

Por exemplo, uma janela de visualização de computador pode ser bem diferente de uma janela de visualização em um smartphone, já que ela renderiza mais espaço vertical, o que pode permitir que imagens se encaixem 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 computador.

No entanto, há alguns casos em que é bastante claro que você deve evitar aplicar loading="lazy". Por exemplo, omita o atributo loading="lazy" dos elementos <img> em imagens principais ou outros casos de uso em que os elementos <img> provavelmente aparecem acima da dobra ou perto da parte superior 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 janela de visualização. Isso significa que, se um elemento <img> na janela de visualização visível tiver um atributo loading="lazy", ele só será solicitado depois que todo o CSS for baixado, analisado e aplicado à página, em vez de ser buscado assim que for descoberto pelo scanner de pré-carregamento na marcação bruta.

Como o atributo loading no elemento <img> é compatível com todos os principais navegadores, não é necessário usar JavaScript para carregar imagens de forma lenta. 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

Carregamento lento de elementos <iframe>

O carregamento lento de elementos <iframe> até que eles fiquem visíveis na janela de visualização pode economizar dados significativos e melhorar o carregamento de recursos críticos necessários para o carregamento da 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 sub-recursos, principalmente JavaScript, o que pode afetar consideravelmente o INP de uma página se as tarefas nesses frames exigirem um tempo de processamento significativo.

Incorporações de terceiros são um caso de uso comum para elementos <iframe>. Por exemplo, players de vídeo incorporados ou postagens de redes sociais geralmente usam elementos <iframe> e exigem um número significativo de sub-recursos, 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 economiza mais de 200 KiB, a maior parte em JavaScript.

De qualquer forma, sempre que você tiver um <iframe> abaixo da dobra em uma página, considere muito fazer o carregamento lento se não for essencial carregar o conteúdo imediatamente. Isso pode melhorar significativamente a experiência do usuário.

O atributo loading para elementos <iframe>

O atributo loading em elementos <iframe> também é compatível com todos os principais navegadores. Os valores do atributo loading e os comportamentos 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 sub-recursos dele imediatamente.
  • O "lazy" adia o carregamento do HTML do elemento <iframe> e dos subrecursos até que ele esteja a 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 carregá-la sob demanda em resposta a uma interação do usuário. Isso pode ser feito mostrando uma imagem ou outro elemento HTML adequado até que o usuário interaja com ele. Depois que o usuário interagir com o elemento, você poderá substituí-lo pela incorporação de terceiros. Essa técnica é conhecida como fachada.

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

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

Além de melhorar o carregamento inicial da página, outra vantagem importante é que, se o usuário nunca reproduzir o vídeo, os recursos necessários para entregá-lo nunca serão baixados. Esse é um bom padrão, já que garante que o usuário baixe apenas o que ele realmente quer, sem fazer suposições possivelmente incorretas 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 baixa quantidades significativas de JavaScript que podem afetar negativamente o carregamento da página e a capacidade de resposta à entrada do usuário. Assim como acontece com o carregamento de qualquer coisa antecipadamente, o custo é incorrido no momento do carregamento, mas, no caso de um widget de chat, nem todo usuário não pretende interagir com ele.

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

Embora seja possível criar suas próprias fachadas, 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 em JavaScript

Se você precisar carregar <video> elementos, imagens poster do elemento <video>, imagens carregadas pela propriedade CSS background-image ou outros elementos não compatíveis, use uma solução de carregamento lento baseada em JavaScript, como lazysizes ou yall.js. Isso porque o carregamento lento desses tipos de recursos não é um recurso no nível do navegador.

Em particular, elementos <video> de reprodução automática e em loop sem uma faixa de áudio são uma alternativa muito mais eficiente do que usar GIFs animados, que geralmente são várias 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. Assim, é possível reconhecer quando um elemento entra na janela de visualização do usuário. Se a imagem estiver visível ou se aproximando da janela de visualização, a biblioteca JavaScript vai 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 quer fazer o carregamento lento dele com uma solução em JavaScript. Isso é possível com yall.js usando 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, yall.js observa todos os elementos HTML qualificados com uma classe de "lazy". Depois que yall.js é carregado e executado na página, o vídeo não é carregado até que o usuário role a tela até a janela de visualização. Nesse momento, os atributos data-src nos elementos <source> filhos do elemento <video> são substituídos por atributos src, que enviam uma solicitação para baixar o 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>?

"lazy"
"eager"

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

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

Quando uma fachada é uma técnica útil?

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

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

Agora que você já sabe como carregar imagens e elementos <iframe> de forma lenta, está em uma boa posição para garantir que as páginas carreguem mais rápido e respeitem 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, você vai aprender sobre pré-busca e pré-renderização e como essas técnicas, quando usadas com cuidado, podem acelerar substancialmente as navegações para páginas subsequentes, carregando-as com antecedência.