React中如何实现渐进增强的图片懒加载兼容旧浏览器?

ლ雨诺 阅读 14

我在用React做图片懒加载时遇到了问题,用IntersectionObserver实现的方案在IE11完全失效,基础图片都不显示了。我试过在组件里这样写:


function LazyImage({ src }) {
  const imgRef = useRef();
  useEffect(() => {
    const observer = new IntersectionObserver(entries => {
      if (entries[0].isIntersecting) {
        imgRef.current.src = src;
        observer.unobserve(imgRef.current);
      }
    });
    observer.observe(imgRef.current);
    return () => observer.disconnect();
  }, []);
  return <img ref={imgRef} src="" />;
}

但这样写的话,旧浏览器连基础的占位图都不会显示,用户会看到大片空白。我应该怎么在保持现代实现的同时,确保基础体验?有没有优雅的回退方案?

我来解答 赞 4 收藏
二维码
手机扫码查看
1 条解答
技术岳阳
你这个写法在不支持 IntersectionObserver 的浏览器里确实会出问题,因为 JS 里面直接走了 observe 流程,但旧浏览器压根没有这个 API,而且你初始 src 是空的,连占位图都没有,用户当然看到一片空白。

正确的做法是做渐进增强:先保证基础 HTML 能显示一个默认图或者低清图,再用 JS 增强加载高清图。同时对不支持 IntersectionObserver 的环境做降级,比如直接加载图片或者用 scroll 事件模拟。

你可以这样改:

function LazyImage({ src, fallbackSrc = '/placeholder.jpg' }) {
const imgRef = useRef();

useEffect(() => {
// 检查是否支持 IntersectionObserver
if (!('IntersectionObserver' in window)) {
// 不支持就直接加载真实图片
imgRef.current.src = src;
return;
}

const observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
imgRef.current.src = src;
observer.unobserve(imgRef.current);
}
});

observer.observe(imgRef.current);

return () => observer.disconnect();
}, [src]);

return ;
}


关键点:

1. 给 img 一个 fallbackSrc 作为初始 src,确保即使 JS 不执行或者报错,也能显示一张占位图
2. 加个 loading="lazy",现代浏览器原生懒加载会接管,算是双重保障
3. JS 里面先判断有没有 IntersectionObserver,没有就直接赋值 src,别走 observe 流程
4. 如果你真要兼容 IE11,记得 polyfill 或者用定时检测位置的方式回退,但一般项目到这一步就够了

这样写,老浏览器至少能看到占位图,不会白屏,新浏览器该懒加载懒加载,体验也更好。
点赞 2
2026-02-12 13:00