【问题标题】:Lazy load images (webp, jpg) with picture, source and img tags (React)延迟加载带有图片、源代码和 img 标签的图像(webp、jpg)(React)
【发布时间】:2019-11-25 11:06:10
【问题描述】:

我目前正在尝试使用 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,但可以在&lt;source /&gt; 标签内提供图像,浏览器将决定加载哪个图像,&lt;img /&gt; 也将用作后备。

我的 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 来加载以显示图像。不幸的是,我不能只是切换到收听webp src,因为在 Safari 等浏览器中它将无法加载......

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

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

【问题讨论】:

    标签: javascript reactjs image jpeg webp


    【解决方案1】:

    您可以使用 IntersectionObserver Api。

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

    Intersection Observer API

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-27
      • 1970-01-01
      相关资源
      最近更新 更多