延迟加载带有 picture、source 和 img 标签的图像(webp、jpg)(React)
Lazy load images (webp, jpg) with picture, source and img tags (React)
我目前正在尝试使用 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加载。不幸的是,我不能只切换到收听 webp
src,因为在像 Safari 这样的浏览器中它将无法加载...
可能我可以尝试并行加载两种资源(webp
和 jpg
)并在第一个资源解析时更新状态。然而,这感觉就像提出更多请求而不是实际优化性能。
您认为这里的好方法是什么?还是我走错了方向?谢谢!
您可以使用 IntersectionObserver Api。
首先加载一个占位符,当元素相交时,您可以将占位符与您想要的 src 切换,这样您只能在元素在视图中时渲染图像
我目前正在尝试使用 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加载。不幸的是,我不能只切换到收听 webp
src,因为在像 Safari 这样的浏览器中它将无法加载...
可能我可以尝试并行加载两种资源(webp
和 jpg
)并在第一个资源解析时更新状态。然而,这感觉就像提出更多请求而不是实际优化性能。
您认为这里的好方法是什么?还是我走错了方向?谢谢!
您可以使用 IntersectionObserver Api。
首先加载一个占位符,当元素相交时,您可以将占位符与您想要的 src 切换,这样您只能在元素在视图中时渲染图像