延迟加载带有图片,源和img标签的图像(webp,jpg)(React)



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

我最初的解决方案是一种非常简单和基本的方法。我使用ImageAPI 并收听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格式的支持不是很好,但可以在<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>
);
}

这里的问题是我仍在收听要加载的原始jpgsrc 以显示图像。不幸的是,我不能只是切换到收听webpsrc,因为在 Safari 等浏览器中它将无法加载......

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

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

您可以使用 IntersectionObserver API。

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

交叉观察器 API

最新更新