Práticas recomendadas de carregamento lento

Embora o carregamento lento de imagens e vídeos tenha uma performance positiva e mensurável benefícios, essa não é uma tarefa a ser encarada de forma leviana. Se você errar, pode haver pode ter consequências indesejadas. Por isso, é importante ter os seguintes as preocupações em mente.

Lembre-se da dobra

Pode ser tentador fazer o carregamento lento de todos os recursos de mídia na página com JavaScript, mas você precisa resistir a essa tentação. Qualquer item acima do ela não pode ser carregada lentamente. Esses recursos devem ser considerados essenciais ativos e, portanto, devem ser carregados normalmente.

O carregamento lento atrasa o carregamento de recursos até que o DOM seja interativo. quando os scripts terminarem de carregar e iniciarem a execução. Para imagens abaixo do tudo bem, mas recursos críticos acima da dobra devem ser carregados o elemento <img> padrão para que sejam exibidos assim que possível.

É claro que a posição da dobra não está tão clara hoje em dia, quando os sites são visualizados em tantas telas de tamanhos variados. O que fica acima da dobra em um laptop podem muito bem estar abaixo dela em dispositivos móveis. Não há conselhos à prova de balas e como lidar com isso de maneira ideal em todas as situações. Você vai precisar realizar uma inventário de recursos críticos da sua página e carregue essas imagens em de maneira

Além disso, talvez você não queira ser tão rigoroso com a linha da dobra quanto limite para acionar o carregamento lento. Pode ser mais ideal para seus propósitos estabelecer uma zona de buffer um pouco abaixo da dobra para que as imagens comecem carregando bem antes de o usuário rolar a tela até a janela de visualização. Por exemplo, o A API Intersection Observer permite especificar uma propriedade rootMargin em uma de opções ao criar uma nova instância de IntersectionObserver. Isso efetivamente fornece um buffer aos elementos, que aciona o comportamento de carregamento lento antes o elemento está na janela de visualização:

let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
  // lazy-loading image code goes here
}, {
  rootMargin: "0px 0px 256px 0px"
});

Se o valor de rootMargin for semelhante aos valores que você especificaria para um CSS margin. Nesse caso, o margem inferior do elemento observado (a janela de visualização do navegador por padrão, mas pode ser mudado para um elemento específico usando a propriedade root) é ampliado em 256 pixels. Isso significa que a função de retorno de chamada será executada quando um elemento de imagem for dentro de 256 pixels da janela de visualização, e a imagem começará a ser carregada antes de o usuário realmente vê-lo.

Para conseguir esse mesmo efeito em navegadores incompatíveis com o Intersection Observe, use o código de manipulação de evento de rolagem e ajuste as Verificação getBoundingClientRect para incluir um buffer.

Mudança de layout e marcadores de posição

O carregamento lento de mídia pode causar mudança no layout se marcadores não forem usados. Essas mudanças podem desorientar os usuários e acionar um layout DOM caro operações que consomem recursos do sistema e contribuem para instabilidade. No mínimo, use um marcador de posição de cor sólida que ocupe as mesmas dimensões imagem de destino ou técnicas como LQIP ou SQIP, que sugerem o conteúdo de uma mídia antes de carregar.

Para tags <img>, src precisa apontar inicialmente para um marcador até que atributo será atualizado com o URL final da imagem. Use o atributo poster em um <video> que aponte para uma imagem de marcador. Além disso, use width e height nas tags <img> e <video>. Isso garante que a transição de marcadores de posição para imagens finais não altera o tamanho renderizado do elemento enquanto a mídia é carregada.

Atrasos na decodificação de imagens

Carregar imagens grandes em JavaScript e soltá-las no DOM pode unir o linha de execução principal, fazendo com que a interface do usuário pare de responder por um curto período o tempo de decodificação. Decodificação assíncrona de imagens usando o decode método antes de inseri-los no DOM pode reduzir esse tipo de instabilidade, mas cuidado: ele ainda não está disponível em todos os lugares e aumenta a complexidade da lógica do carregamento lento. Se quiser usá-lo, será necessário verificar. Mostramos abaixo como usar Image.decode() com um substituto:

var newImage = new Image();
newImage.src = "my-awesome-image.jpg";

if ("decode" in newImage) {
  // Fancy decoding logic
  newImage.decode().then(function() {
    imageContainer.appendChild(newImage);
  });
} else {
  // Regular image load
  imageContainer.appendChild(newImage);
}

Confira este link do CodePen para ver código semelhante a este exemplo em ação. Se a maioria das imagens for pequena, isso pode não ajudar muito, mas certamente pode ajudar a reduzir a instabilidade quando carregamento lento de imagens grandes e inseri-las no DOM.

Quando o carregamento não carrega

Às vezes, os recursos de mídia não carregam por algum motivo e erros antes que ocorram mudanças. Quando isso pode acontecer? Depende, mas veja este cenário hipotético para você: você tem uma política de armazenamento em cache HTML por um curto período de tempo (por exemplo, cinco minutos) e o usuário acessar o site ou deixar uma guia desatualizada aberta por por um longo período de tempo (por exemplo, várias horas) e volta para ler seu conteúdo. Em algum momento desse processo, ocorre uma reimplantação. Durante essa implantação, um o nome do recurso de imagem for alterado devido ao controle de versões baseado em hash ou for removido completamente. Quando o usuário faz o carregamento lento da imagem, o recurso é indisponível, o que resulta em falha.

Embora essas sejam ocorrências relativamente raras, pode ser útil ter um backup se o carregamento lento falhar. Para imagens, essa solução pode ser algo como isso:

var newImage = new Image();
newImage.src = "my-awesome-image.jpg";

newImage.onerror = function(){
  // Decide what to do on error
};
newImage.onload = function(){
  // Load the image
};

O que você decide fazer em caso de erro depende do aplicativo. Para exemplo, é possível substituir a área de espaço reservado da imagem por um botão que permita o usuário tentar carregar a imagem novamente ou simplesmente exibir uma mensagem de erro na área de espaço reservado da imagem.

Outros cenários também podem surgir. Não importa o que você faça, nunca é má ideia sinalizar ao usuário quando um erro ocorrer e possivelmente sugerir uma ação tomar se algo der errado.

Disponibilidade do JavaScript

Não presuma que o JavaScript está sempre disponível. Se você for imagens de carregamento lento, considere oferecer a marcação <noscript>, que mostrará as imagens em caso o JavaScript não esteja disponível. O exemplo substituto mais simples possível envolve usando elementos <noscript> para exibir imagens se o JavaScript estiver desativado:

Sou uma imagem!

Se o JavaScript estiver desativado, os usuários verão tanto a imagem do marcador de posição quanto a contida com os elementos <noscript>. Para contornar isso, coloque uma classe de no-js na tag <html> desta forma:

<html class="no-js">

Em seguida, coloque uma linha de script in-line na <head> antes das folhas de estilo são solicitados usando tags <link> que removem a classe no-js do <html>. se o JavaScript estiver ativado:

<script>document.documentElement.classList.remove("no-js");</script>

Por fim, use CSS para ocultar elementos com uma classe de lentidão O JavaScript não está disponível:

.no-js .lazy {
  display: none;
}

Isso não impede o carregamento das imagens de marcador de posição, mas o resultado é mais desejáveis. As pessoas com o JavaScript desativado recebem algo além do marcador imagens, o que é melhor do que espaços reservados e sem conteúdo de imagem significativo tudo.