Lazy loading para imagens em background
Published: 2023-04-13 11:22:30

Recentemente, estava desenvolvendo um projeto com meu parceiro Anderson Santana para um cliente da [UpCubo](https://www.linkedin.com/company/upcubo/). 

Um dos requisitos deste projeto seria uma seção com um carrossel de 8 imagens sendo alternadas a cada 5 segundos em background com um texto em destaque desta maneira:


![Exemplo de seção de um site que destaca um texto com uma imagem de fundo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wfpb0ikuy3xmzfutxpz0.png)

A primeira vista, essa pode ser uma tarefa simples, mas existem alguns detalhes importantes a serem observados em relação à performance.

No mundo do desenvolvimento web, a performance é uma preocupação constante para garantir uma boa experiência do usuário. Recentemente, o Google anunciou o Core Web Vitals, um conjunto de métricas que avaliam a qualidade da experiência de um usuário ao acessar um site, e isso trouxe ainda mais importância ao tema.

Como resolver?

Lembrando que essa é apenas uma das muitas formas de implementar essa funcionalidade.

Durante minhas pesquisas, a maneira mais performática de fazer essa implementação seria utilizando o IntersectionObserver do JavaScript. Dessa forma, poderíamos disparar o início do carregamento das imagens apenas quando a seção estivesse prestes a ficar visível na tela do usuário.

Com isso, o carregamento inicial da página não seria prejudicado pelo tamanho dessas imagens.

O código ficou assim:

```javascript

const images = [
 "/img/img-example-1.jpg",
 "/img/img-example-2.jpg",
 "/img/img-example-3.jpg",
 "/img/img-example-4.jpg",
 "/img/img-example-5.jpg",
 "/img/img-example-6.jpg",
 "/img/img-example-7.jpg",
 "/img/img-example-8.jpg",
];


const animationDuration = 5000; //milesseconds
let intervalId;


// aguarda a página carregar para executar a função initLazyLoadBackground
document.addEventListener("DOMContentLoaded", () => initLazyLoadBackground());


// Função que inicia o lazy load de imagens de fundo
function initLazyLoadBackground() {
  // Seleciona todos os elementos com a classe "lazy-background"
  const elementLazyBackground = document.querySelector(".lazy-background");

  // Verifica se o IntersectionObserver está disponível no navegador
  if ("IntersectionObserver" in window) {
    // Cria um novo IntersectionObserver e passa como callback a função lazyLoadIntersectionObserver
    const lazyBackgroundObserver = new IntersectionObserver(
      lazyLoadIntersectionObserver
    );

    // Observa o elemento com a classe "lazy-background"
    lazyBackgroundObserver.observe(elementLazyBackground);
  }
}

// Função que é executada quando um elemento com a classe "lazy-background" é observado
function lazyLoadIntersectionObserver(entries, observer) {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      // Seleciona o elemento que será utilizado como fundo
      const elementToChangeBgImage = document.querySelector(".lazy-background");

      // Índice da imagem que será exibida
      let backgroundImageIndex = 0;

      // Função que altera o fundo do elemento selecionado a cada intervalo de tempo
      function changeBackgroundImage() {
        const newBackground = `url("${images[backgroundImageIndex]}")`;
        elementToChangeBgImage.style.backgroundImage = newBackground;

        // Incrementa o índice da imagem e reinicia caso chegue ao final do array
        backgroundImageIndex++;
        if (backgroundImageIndex >= images.length) backgroundImageIndex = 0;
      }

      // Inicia a animação e armazena o id do intervalo em uma variável
      intervalId = setInterval(changeBackgroundImage, animationDuration);

      // Remove o elemento observado do IntersectionObserver
      observer.unobserve(entry.target);
    } else if (intervalId) {
      // Encerra a animação caso o elemento deixe de ser observado
      clearInterval(intervalId);
      intervalId = null;
    }
  });
}

```
Deste modo, a primeira imagem do carrossel será carregada apenas (e se) o usuário fizer o scroll da página até chegar na seção. 


![Imagem que mostra como as imagens podem ser carregadas sob demanda com a utilização da técnica de lazy loading](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1cgwr6jbiltppy7o72c1.gif)
 

Como essas imagens serão apenas para efeitos ilustrativos e não trazem nenhum tipo de conteúdo adicional para a informação, isso não afetará negativamente o SEO da página.


O tempo de carregamento de uma página é um dos fatores mais importantes na experiência do usuário. Páginas que carregam lentamente podem afetar a satisfação do usuário e até mesmo influenciar no ranqueamento e por consequência na taxa de conversão de um site. 

Vale lembrar que o desempenho de uma página depende de vários outros fatores, e o uso de lazy loading para imagens de fundo pode ser apenas uma das estratégias para otimização de performance. Outras técnicas, como compressão de imagens, cache e otimização de código, também devem ser consideradas.

Imagens são essenciais para a web e vão sempre estar presentes, no entanto, podemos ser criativos para economizar valiosos kbps :)

Fique a vontade para me adicionar no [Linkedin](https://www.linkedin.com/in/clayton-rafael/) 🚀


Referências: 
https://web.dev/lazy-loading-images/