带有图片,源和img标签的惰性加载图像(webp,jpg)(反应)

时间:2019-07-16 16:37:19

标签: javascript reactjs image jpeg webp

我目前正在尝试用React实现一个延迟加载的图像组件。

我最初的解决方案是一种非常简单且基本的方法。 我使用了Image API,并听了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;
}

React组件的代码如下:

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

  return (
    <div className="container">
      {isLoaded ? (
        <img src={src} {...props} />
      ) : (
        <div className="preloader" />
      )}
    </div>
  );
}

现在,我想获得webp格式的好处,该格式在我加载图像的API所支持。

尽管浏览器支持webp格式is not that good,但可以在<source />标签内提供图像,浏览器将决定加载哪个图像,也将使用<img />作为备用。

我的React组件已相应更新:

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>
  );
}

问题,这是我仍在监听要加载的原始jpg src以显示图像。不幸的是,我不能像在Safari这样的浏览器中那样切换到监听webp src,因为它将无法加载...

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

您认为这里的一种好方法是什么?还是我走错了方向?谢谢!

1 个答案:

答案 0 :(得分:0)

您可以使用IntersectionObserver Api。

首先加载一个占位符,当元素相交时,您可以使用所需的src切换占位符,这样,仅当元素在视图中时才可以渲染图像

Intersection Observer API