You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免react-intersection-observer下图片重复加载?

解决建议

方案1:用状态记录加载状态,保留src仅控制显示隐藏

核心思路是仅在元素首次进入视口时加载图片,之后固定src地址,通过CSS控制图片的显示/隐藏,避免因src重置触发重复请求。

修改后的代码如下:

import * as React from "react";
import { createRoot } from "react-dom/client";
import { useInView } from "react-intersection-observer";
import "./styles.css";

function App() {
  const { ref, inView } = useInView({
    threshold: 0
  });
  // 记录图片是否已完成首次加载
  const [isImageLoaded, setIsImageLoaded] = React.useState(false);

  // 元素首次进入视口时,标记图片为已加载
  React.useEffect(() => {
    if (inView && !isImageLoaded) {
      setIsImageLoaded(true);
    }
  }, [inView, isImageLoaded]);

  return (
    <>
      <div style={{ height: "200vh" }}>eeeeee</div>
      <div ref={ref} className="inview-block">
        <h2>
          <img
            // 加载完成后永久保留真实地址
            src={isImageLoaded ? "https://inviewimaging.com/wp-content/uploads/2015/04/Inview-Graphic.png" : null}
            alt=""
            // 根据是否在视口控制显示状态
            style={{ display: inView ? "block" : "none" }}
          />
        </h2>
      </div>
    </>
  );
}

const root = createRoot(document.getElementById("root"));
root.render(<App />);

方案2:结合原生懒加载,用inView控制显示

如果允许图片DOM提前存在,可直接设置src并开启原生懒加载,通过inView控制显示状态,利用浏览器缓存避免重复请求:

import * as React from "react";
import { createRoot } from "react-dom/client";
import { useInView } from "react-intersection-observer";
import "./styles.css";

function App() {
  const { ref, inView } = useInView({
    threshold: 0
  });
  const IMAGE_URL = "https://inviewimaging.com/wp-content/uploads/2015/04/Inview-Graphic.png";

  return (
    <>
      <div style={{ height: "200vh" }}>eeeeee</div>
      <div ref={ref} className="inview-block">
        <h2>
          <img
            src={IMAGE_URL}
            alt=""
            // 初始隐藏,进入视口后显示,移出则隐藏
            style={{ display: inView ? "block" : "none" }}
            // 开启原生懒加载,仅当元素接近视口时才加载
            loading="lazy"
          />
        </h2>
      </div>
    </>
  );
}

const root = createRoot(document.getElementById("root"));
root.render(<App />);

方案说明

  • 方案1适合需要严格控制初始请求量的场景,仅在元素首次进入视口才加载图片,后续仅切换显示状态。
  • 方案2利用浏览器原生能力实现懒加载,代码更简洁,图片加载后会被浏览器缓存,再次进入视口不会重复发起请求。

内容的提问来源于stack exchange,提问作者user19883277

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 05:15:44