create-react-app加载大量图片出现404错误及卡顿问题求助
问题分析与解决方案
核心问题原因
篡改原数据导致图片URL异常
你在useEffect里使用data.shift(),这个方法会直接修改父组件传递过来的原始data数组,移除数组第一个元素。如果父组件的data是全局状态或复用的数据源,反复调用shift()会破坏原数据,后续渲染时可能拿到undefined的imageURL,浏览器请求无效地址自然返回404。循环多次触发状态更新引发卡顿
循环里每次调用setCards都会触发React组件重渲染,25次循环就会触发25次重渲染,大量DOM更新累积会造成页面卡顿。
修复方案
1. 停止修改原数据,改用切片获取数据
放弃shift()操作,通过索引切片提取需要渲染的元素,保留原数据供后续加载使用。
2. 批量更新状态,减少重渲染次数
一次性计算好需要添加的元素,只调用一次状态更新方法,避免多次重渲染。
3. 实现滚动加载逻辑
监听滚动事件,判断用户滚动到页面底部时,加载下一批图片。
修改后的代码示例
Card组件(无需改动)
const Card = ({name, title, imageURL, categories, leaderSkill, passive, links}) => { return( <> <img src={imageURL} title={`${name} ${title}`} alt={`${name} ${title}`} loading="lazy"/> </> ) } export default Card;
Cards组件(修复+滚动加载实现)
import Card from './Card'; import { useEffect, useState } from 'react'; const Cards = ({ data }) => { const [visibleCount, setVisibleCount] = useState(25); // 初始显示25张 // 监听滚动事件,触发加载更多 useEffect(() => { const handleScroll = () => { // 判断是否滚动到接近页面底部(预留100px提前加载) const isNearBottom = window.innerHeight + window.scrollY >= document.documentElement.scrollHeight - 100; if (isNearBottom && visibleCount < data.length) { // 每次加载25张,不超过总数据长度 setVisibleCount(prev => Math.min(prev + 25, data.length)); } }; window.addEventListener('scroll', handleScroll); // 组件卸载时移除监听,避免内存泄漏 return () => window.removeEventListener('scroll', handleScroll); }, [visibleCount, data.length]); // 从原数据截取需要显示的部分,不修改原数组 const visibleCards = data.slice(0, visibleCount); return( <div className="mt-[5vh] grid grid-cols-[repeat(5,_minmax(10px,_1fr))] lg:grid-cols-[repeat(10,_minmax(10px,_1fr))] gap-1"> { visibleCards.map(el => { return(<Card key={el.id} name={el.name} title={el.title} imageURL={el.imageURL} categories={el.categories} leaderSkill={el.leaderSkill} passive={el.passive} links={el.links}/>); }) } </div> ) } export default Cards;
额外优化建议
- 给图片添加固定尺寸的容器,避免图片加载时布局跳动,进一步降低卡顿感。
- 可添加加载状态提示(如滚动到底部时显示"加载中..."),提升用户体验。
- 如果图片资源较大,可配合低分辨率占位图,优化加载过程的视觉体验。
内容的提问来源于stack exchange,提问作者Eiron
相关产品推荐
相关产品推荐

