export function LazyImage(props: LazyImageProps) {
const {
src,
height,
width,
alt,
styles,
rootMargin = '0px',
threshold = 0,
loadImmediately
} = props;
const supportsNativeLazyLoading = 'loading' in HTMLImageElement.prototype;
const { ref, inView } = useInView({
rootMargin,
threshold,
triggerOnce: true
});
const [srcPath, setSrcPath] = useState(null);
const preloadImage = (url: string) => {
return new Promise((resolve, reject) => {
const image = new Image();
image.onload = resolve;
image.onerror = reject;
image.src = url;
});
};
useEffect(() => {
const checkPreloader = async () => {
try {
await preloadImage(src);
// eslint-disable-next-line no-empty
} catch (error) {
} finally {
setSrcPath(src);
}
};
if (supportsNativeLazyLoading) {
setSrcPath(src);
return;
}
if (loadImmediately || inView) checkPreloader();
}, [supportsNativeLazyLoading, src, loadImmediately, inView]);
return srcPath ? (
<S.Image
loading={!loadImmediately ? 'lazy' : 'eager'}
src={srcPath}
alt={alt}
height={height}
width={width}
css={styles}
/>
) : (
<S.Preloader
ref={!supportsNativeLazyLoading ? ref : null}
height={height}
width={width}
/>
);
}