Carregamento lento de imagens

As imagens podem aparecer em uma página da Web por estarem inline no HTML como elementos <img>. ou imagens de plano de fundo CSS. Nesta postagem, você descobrirá como fazer o carregamento lento desses dois tipos de imagem.

Imagens inline

As candidatas mais comuns para o carregamento lento são imagens usadas em elementos <img>. Com imagens inline, temos três opções de carregamento lento: que podem ser usados em combinação para a melhor compatibilidade entre navegadores:

Como usar o carregamento lento no nível do navegador

O Chrome e o Firefox são compatíveis com o carregamento lento com o atributo loading. Esse atributo pode ser adicionado a elementos <img> e <iframe>. O valor lazy instrui o navegador a carregar a imagem imediatamente se ela estiver na janela de visualização. e buscar outras imagens quando o usuário rolar a tela perto delas.

Consulte o campo loading dos compatibilidade do navegador para obter detalhes sobre os navegadores compatíveis. Se o navegador não for compatível com o carregamento lento, o atributo será ignorado e as imagens serão carregadas imediatamente, como de costume.

Para a maioria dos sites, adicionar esse atributo a imagens inline melhora o desempenho e salvar os usuários carregando imagens que talvez eles nem nunca rolem. Se você tiver um grande número de imagens e quiser garantir que os usuários de navegadores sem suporte ao carregamento lento se beneficiem você precisará combinar isso com um dos métodos explicados a seguir.

Para saber mais, consulte Carregamento lento no nível do navegador para a Web.

Como usar o Intersection Observer

Para o carregamento lento de polyfill de elementos <img>, usamos JavaScript para verificar se eles estão na janela de visualização. Se forem, os atributos src (e às vezes srcset) serão preenchido com URLs para o conteúdo da imagem desejado.

Se você já escreveu um código de carregamento lento antes, talvez já tenha concluído sua tarefa. usando manipuladores de eventos como scroll ou resize. Embora essa abordagem seja mais compatíveis com todos os navegadores, os navegadores modernos oferecem uma interface eficiente de verificar a visibilidade do elemento por meio do API Intersection Observer.

O Intersection Observer é mais fácil de usar e ler do que o código que depende de várias manipuladores de eventos, porque só é preciso registrar um observador para em vez de escrever códigos tediosos de detecção de visibilidade. Todos resta decidir o que fazer quando um elemento está visível. Vamos supor este padrão básico de marcação para seus elementos <img> de carregamento lento:

<img class="lazy" src="placeholder-image.jpg" data-src="image-to-lazy-load-1x.jpg" data-srcset="image-to-lazy-load-2x.jpg 2x, image-to-lazy-load-1x.jpg 1x" alt="I'm an image!">

Há três partes relevantes dessa marcação nas quais você deve se concentrar:

  1. O atributo class, que é usado para selecionar o elemento JavaScript.
  2. O atributo src, que referencia uma imagem de marcador que aparecerá quando a página é carregada pela primeira vez.
  3. Os atributos data-src e data-srcset, que são atributos de marcador de posição contendo o URL da imagem que você carregará assim que o elemento estiver na janela de visualização.

Agora vamos aprender a usar o Intersection Observer no JavaScript para fazer o carregamento lento. imagens usando este padrão de marcação:

document.addEventListener("DOMContentLoaded", function() {
  var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));

  if ("IntersectionObserver" in window) {
    let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          let lazyImage = entry.target;
          lazyImage.src = lazyImage.dataset.src;
          lazyImage.srcset = lazyImage.dataset.srcset;
          lazyImage.classList.remove("lazy");
          lazyImageObserver.unobserve(lazyImage);
        }
      });
    });

    lazyImages.forEach(function(lazyImage) {
      lazyImageObserver.observe(lazyImage);
    });
  } else {
    // Possibly fall back to event handlers here
  }
});

No evento DOMContentLoaded do documento, esse script consulta o DOM para todos Elementos <img> com uma classe de lazy. Se o Intersection Observer estiver disponível, crie um novo observador que execute um callback quando os elementos img.lazy entrarem no janela de visualização.

O Intersection Observer está disponível em todos os navegadores modernos. Portanto, usá-lo como um polyfill para loading="lazy" vai garantir que o carregamento lento esteja disponível para a maioria dos visitantes.

Imagens em CSS

Embora as tags <img> sejam a maneira mais comum de usar imagens em páginas da Web, também podem ser invocados pela interface background-image e outras propriedades. O carregamento lento no navegador não se aplica a imagens de plano de fundo CSS. Por isso, se você tiver imagens de plano de fundo para carregar lentamente, considere outros métodos.

Ao contrário dos elementos <img>, que são carregados de qualquer forma da visibilidade, o comportamento de carregamento de imagens no CSS é feito especulação. Quando o documento e o objeto CSS de ML e renderizar árvore são criados, o navegador examina como o CSS é aplicado a um documento antes solicitando recursos externos. Se o navegador tiver determinado uma regra CSS que envolvem um recurso externo não se aplica ao documento, já que é construído, o navegador não o solicita.

Esse comportamento especulativo pode ser usado para adiar o carregamento de imagens em CSS usando JavaScript para determinar quando um elemento está na janela de visualização, e em seguida, aplicando uma classe a esse elemento que aplica estilo invocando uma imagem de plano de fundo. Isso faz com que o download da imagem seja feito quando necessário. e não no carregamento inicial. Por exemplo, vamos pegar um elemento que contenha uma imagem grande de plano de fundo principal:

<div class="lazy-background">
  <h1>Here's a hero heading to get your attention!</h1>
  <p>Here's hero copy to convince you to buy a thing!</p>
  <a href="/buy-a-thing">Buy a thing!</a>
</div>

O elemento div.lazy-background normalmente contém o plano de fundo hero. invocada por algum CSS. No entanto, neste exemplo de carregamento lento, é possível isolar a propriedade background-image do elemento div.lazy-background usando um objeto visible. adicionada ao elemento quando ele está na janela de visualização:

.lazy-background {
  background-image: url("hero-placeholder.jpg"); /* Placeholder image */
}

.lazy-background.visible {
  background-image: url("hero.jpg"); /* The final image */
}

A partir daqui, use JavaScript para verificar se o elemento está na janela de visualização (com Intersection Observer!) e adicione a classe visible ao div.lazy-background nesse momento, que carrega a imagem:

document.addEventListener("DOMContentLoaded", function() {
  var lazyBackgrounds = [].slice.call(document.querySelectorAll(".lazy-background"));

  if ("IntersectionObserver" in window) {
    let lazyBackgroundObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          entry.target.classList.add("visible");
          lazyBackgroundObserver.unobserve(entry.target);
        }
      });
    });

    lazyBackgrounds.forEach(function(lazyBackground) {
      lazyBackgroundObserver.observe(lazyBackground);
    });
  }
});

Efeitos na Largest Contentful Paint (LCP)

O carregamento lento é uma ótima otimização que reduz o uso geral de dados e a contenção de rede durante a inicialização, adiando o carregamento de imagens para quando elas são realmente necessárias. Isso pode melhorar o tempo de inicialização e reduzir o processamento na linha de execução principal, reduzindo o tempo necessário para decodificações de imagens.

No entanto, o carregamento lento é uma técnica que pode afetar a Maior LCP de pintura de conteúdo do seu site de maneira negativa, se você quiser muito usar essa técnica. Evite o carregamento lento de imagens que estão na janela de visualização durante a inicialização.

Ao usar carregadores lentos baseados em JavaScript, evite o carregamento lento de imagens na janela de visualização, porque essas soluções geralmente usam um atributo data-src ou data-srcset como marcador de posição para os atributos src e srcset. O problema é que o carregamento dessas imagens atrasa porque o verificador de pré-carregamento do navegador não consegue encontrá-las durante a inicialização.

Mesmo o uso do carregamento lento no nível do navegador de uma imagem na janela de visualização pode não funcionar. Quando loading="lazy" é aplicado a uma imagem na janela de visualização, essa imagem é atrasada até que o navegador tenha certeza de que está nessa janela, o que pode afetar a LCP da página.

Nunca carregue lentamente imagens visíveis na janela de visualização durante a inicialização. Esse padrão afeta negativamente a LCP do site e, portanto, a experiência do usuário. Se você precisar de uma imagem na inicialização, carregue-a o mais rápido possível sem fazer o carregamento lento.

Bibliotecas de carregamento lento

Você deve usar o carregamento lento no nível do navegador sempre que possível, mas se isso não for viável, como um grupo significativo de usuários que ainda depende de navegadores mais antigos, as seguintes bibliotecas podem ser usadas para fazer o carregamento lento de imagens:

  • Lazysizes é um utilitário lento que faz o carregamento lento de imagens e iframes. O padrão usado é bastante semelhante aos exemplos de código mostrados aqui, já que se vincula automaticamente a uma lazyload em elementos <img>, e exige a especificação de URLs de imagem em Atributos data-src e/ou data-srcset, cujo conteúdo é trocado em atributos src e/ou srcset, respectivamente. Ele usa Intersecção Observer (que você pode usar com polyfill), podendo ser estendido por vários plug-ins para executar ações como carregar vídeos lentamente. Saiba mais sobre o uso da Lazysizes (link em inglês).
  • vanilla-lazyload é um uma opção leve para imagens de carregamento lento, imagens de plano de fundo, vídeos, iframes, e scripts. Ele usa o Intersection Observer, oferece suporte a imagens responsivas e ativa o carregamento lento no nível do navegador.
  • O lozad.js é uma outra interface que usa apenas Intersection Observer. Por isso, ele tem alto desempenho, mas precisará ser polyfill antes de ser usado em navegadores mais antigos.
  • Se você precisar de uma biblioteca de carregamento lento específica para React, considere react-lazyload. Embora não usa Intersection Observer, ele fornece um método familiar de leitura lenta carregando imagens para quem está acostumado a desenvolver aplicativos com React.