Javascript 延迟加载图像(webp、jpg),带有图片、源和img标记(React)

Javascript 延迟加载图像(webp、jpg),带有图片、源和img标记(React),javascript,reactjs,image,jpeg,webp,Javascript,Reactjs,Image,Jpeg,Webp,我正在尝试用React实现一个延迟加载映像组件 我最初的解决方案是非常简单和基本的方法我使用并收听了onload事件。 这里有一个React钩子的示例,该钩子处理此功能: function useImage(src) { const [loaded, setLoaded] = useState(false); useEffect(() => { if (!loaded) { loadImage(); } function loadImage(

我正在尝试用React实现一个延迟加载映像组件

我最初的解决方案是非常简单和基本的方法我使用并收听了
onload
事件。

这里有一个React钩子的示例,该钩子处理此功能:

function useImage(src) {
  const [loaded, setLoaded] = useState(false);

  useEffect(() => {
    if (!loaded) {
      loadImage();
    }

    function loadImage() {
      const img = new Image();
      img.onload = () => setLoaded(true);
      img.src = src;
    }
  });

  return loaded;
}
反应组件的代码如下所示:

function LazyImage({ src, ...props }) {
  const isLoaded = useImage(src);

  return (
    <div className="container">
      {isLoaded ? (
        <img src={src} {...props} />
      ) : (
        <div className="preloader" />
      )}
    </div>
  );
}
这里的问题是,我仍然在听原始的
jpg
src来加载以显示图像。不幸的是,我不能切换到只听
webp
src,因为在像Safari这样的浏览器中,它将无法加载

可能我可以尝试并行加载两个资源(
webp
jpg
),并在第一个资源解析时更新状态。然而,这感觉像是提出更多的请求,而不是实际优化性能


你认为在这里什么是好方法?还是我走错了方向?谢谢

您可以使用IntersectionObserver Api

首先加载一个占位符,当元素相交时,您可以将占位符与所需的src切换,这样您只能在元素处于视图中时渲染图像

function LazyImage({ src, ...props }) {
  const webpSrc = getWebpSrc(src);
  const isLoaded = useImage(src);

  return (
    <div className="container">
      {isLoaded ? (
        <picture>
          <source srcset={webpSrc} type="image/webp" />
          <source srcset={src} type="image/jpeg" />
          <img src={src} {...props} />
        </picture>
      ) : (
        <div className="preloader" />
      )}
    </div>
  );
}