Skip to content

Instantly share code, notes, and snippets.

@Slashgear
Last active March 27, 2019 17:56
Show Gist options
  • Select an option

  • Save Slashgear/850fd25a20bebe1e75f02fdb8343c883 to your computer and use it in GitHub Desktop.

Select an option

Save Slashgear/850fd25a20bebe1e75f02fdb8343c883 to your computer and use it in GitHub Desktop.
Intersection Observer trick
import React, { useState, useEffect } from "react";
import styled from "styled-components";
const Image = styled.img`
display: block;
height: 100px;
width: 100px;
`;
const placeHolder =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkqAcAAIUAgUW0RjgAAAAASUVORK5CYII=";
export const LazyImage = ({ src, alt }) => {
const [imageSrc, setImageSrc] = useState(placeHolder);
const [imageRef, setImageRef] = useState();
useEffect(() => {
let observer;
let didCancel = false;
if (imageRef && imageSrc === placeHolder) {
if (IntersectionObserver) {
observer = new IntersectionObserver(
entries => {
entries.forEach(entry => {
// when image is visible in the viewport + rootMargin
if (!didCancel && (entry.intersectionRatio > 0 || entry.isIntersecting)) {
setImageSrc(src);
}
});
},
{
threshold: 0.01,
rootMargin: "75%"
}
);
observer.observe(imageRef);
} else {
// Old browsers fallback
setImageSrc(src);
}
}
return () => {
didCancel = true;
// on component unmount, we remove the listner
if (observer && observer.unobserve) {
observer.unobserve(imageRef);
}
};
});
return <Image ref={setImageRef} src={imageSrc} alt={alt} />;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment