@Pavel_Dorozhkin

Как реализовать подмену изображения с нативной поддержкой loading="lazy"?

Всем привет и с наступающим)) Решил сделать компонент для ленивой загрузки картинок, для этого использую react-intersection-observer. С его помощью отслеживаю еще не загрузившуюся картинку и заменяю на лоадер. Захотелось сделать тоже самое с нативным loading="lazy", но беда в том что я не понимаю какое событие генерирует браузер и когда и как его отследить. Начал копать в сторону react-mutation-observer, но не получилось. Возможно всё гораздо проще?)) Есть идеи? Заранее благодарю!
spoiler
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}
    />
  );
}
  • Вопрос задан
  • 42 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы