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:
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.