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

React中如何实现图片懒加载?应在哪个文件层实现该功能?

首先回答你的第一个疑问:是的,常规的图片懒加载逻辑就是只有当图片进入(也可配置提前量,比如距离可视区还有200px时就触发)浏览器的可视区域时,才会发起资源请求,能大幅降低首屏的请求量和加载耗时。不过你现在的代码写法有个坑:你在SportImages.js里提前import了所有图片,这种写法会让构建工具把所有这些图片都标记为首屏依赖,就算你加了懒加载逻辑,这些图片还是会在首屏就全部加载,完全达不到懒加载的效果,这点要先修正。


懒加载逻辑的处理位置建议

不要在统一图片管理文件处理,也不要在每个业务组件重复写,最优方案是封装成通用的懒加载图片组件,理由如下:

  • 图片管理文件只负责维护资源映射关系,和视图渲染逻辑解耦,后续改资源路径只需要改这一个文件
  • 通用组件一次封装全项目复用,后续要加占位图、加载失败兜底、加载动画等功能,只需要改组件代码,不需要挨个改业务逻辑

调整步骤

  1. 先修正图片导入逻辑,避免全量提前加载:
    如果你用的是CRA/Vite等标准React构建工具,把图片放到public/images目录下,修改SportImages.js为直接存路径即可:
// SportImages.js file
export default {
  Football: '/images/football.png',
  Cricket: '/images/cricket.png',
  Soccer: '/images/soccer.png',
  // 剩余图片同理
}

如果不想把图片放到public目录,需要存在src文件夹下的话,删掉所有提前import的语句,配合动态导入使用即可。

  1. 两种懒加载实现方案可选:

方案1:原生属性实现(最简单,兼容95%以上现代浏览器)

直接给img标签加原生loading="lazy"属性即可,不需要额外逻辑:

cards.map(x => {
  return (
    <img 
      src={SportImages[x.image_ref]}
      loading="lazy"
      alt={x.name /* 建议补充alt属性优化无障碍体验 */}
    />
  )
})

方案2:IntersectionObserver自定义实现(兼容性更强,可自定义配置)

封装通用懒加载图片组件,自定义预加载距离、加载状态等:

import { useState, useEffect, useRef } from 'react'

const LazyImg = ({ src, alt, ...rest }) => {
  const [isLoaded, setIsLoaded] = useState(false)
  const imgRef = useRef(null)

  useEffect(() => {
    const observer = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          // 进入可视区后触发加载
          const img = new Image()
          img.src = src
          img.onload = () => {
            setIsLoaded(true)
            observer.unobserve(imgRef.current)
          }
        }
      })
    }, { rootMargin: '200px 0px' }) // 提前200px预加载,避免滑动到位置才加载出现空白

    if (imgRef.current) observer.observe(imgRef.current)
    return () => observer.disconnect()
  }, [src])

  return (
    <div ref={imgRef} {...rest}>
      {isLoaded ? <img src={src} alt={alt} /> : <div className="img-placeholder" />}
    </div>
  )
}

// 业务组件内直接调用
cards.map(x => {
  return <LazyImg src={SportImages[x.image_ref]} alt={x.name} />
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 11:18:02