Introdução
Neste laboratório, exploraremos como implementar o carregamento lento (lazy loading) de imagens em uma aplicação React. O carregamento lento melhora o desempenho da página ao adiar o carregamento de imagens até que sejam necessárias, reduzindo o tempo inicial de carregamento e melhorando a experiência do usuário. Usaremos a API Intersection Observer e os hooks do React para criar um componente reutilizável que suporte o carregamento lento de imagens.
Carregamento Lento de Imagens (Lazy-Loading Image)
index.htmlescript.jsjá foram fornecidos na VM. Em geral, você só precisa adicionar código ascript.jsestyle.css.
Para renderizar uma imagem que suporte carregamento lento, siga estes passos:
- Use o hook
useState()para criar um valor com estado que indica se a imagem foi carregada. - Use o hook
useEffect()para verificar se oHTMLImageElement.prototypecontém'loading'. Isso verifica se o carregamento lento é suportado nativamente. Caso contrário, crie um novoIntersectionObservere useIntersectionObserver.observer()para observar o elemento<img>. Use o valor dereturndo hook para limpar quando o componente for desmontado. - Use o hook
useCallback()para memorizar uma função de callback para oIntersectionObserver. Este callback atualizará a variável de estadoisLoadede usaráIntersectionObserver.disconnect()para desconectar a instância doIntersectionObserver. - Use o hook
useRef()para criar duas refs. Uma manterá o elemento<img>e a outra a instância doIntersectionObserver, se necessário. - Finalmente, renderize o elemento
<img>com os atributos fornecidos. Apliqueloading='lazy'para fazê-lo carregar lentamente, se necessário. UseisLoadedpara determinar o valor do atributosrc.
Aqui está um exemplo de implementação desses passos:
const LazyLoadImage = ({
alt,
src,
className,
loadInitially = false,
observerOptions = { root: null, rootMargin: "200px 0px" },
...props
}) => {
const observerRef = React.useRef(null);
const imgRef = React.useRef(null);
const [isLoaded, setIsLoaded] = React.useState(loadInitially);
const observerCallback = React.useCallback(
(entries) => {
if (entries[0].isIntersecting) {
observerRef.current.disconnect();
setIsLoaded(true);
}
},
[observerRef]
);
React.useEffect(() => {
if (loadInitially) return;
if ("loading" in HTMLImageElement.prototype) {
setIsLoaded(true);
return;
}
observerRef.current = new IntersectionObserver(
observerCallback,
observerOptions
);
observerRef.current.observe(imgRef.current);
return () => {
observerRef.current.disconnect();
};
}, []);
return (
<img
alt={alt}
src={isLoaded ? src : ""}
ref={imgRef}
className={className}
loading={loadInitially ? undefined : "lazy"}
{...props}
/>
);
};
Para usar este componente LazyLoadImage, basta chamá-lo com os atributos src e alt da imagem:
ReactDOM.createRoot(document.getElementById("root")).render(
<LazyLoadImage
src="https://picsum.photos/id/1080/600/600"
alt="Strawberries"
/>
);
Por favor, clique em 'Go Live' no canto inferior direito para executar o serviço web na porta 8080. Em seguida, você pode atualizar a aba Web 8080 para visualizar a página web.
Resumo
Parabéns! Você concluiu o laboratório de Carregamento Lento de Imagens (Lazy-Loading Image). Você pode praticar mais laboratórios no LabEx para aprimorar suas habilidades.