React Native FlatList多选item性能问题:200+图片选中图标响应慢
优化方案
1. 修正FlatList错误配置
- 你当前将
maxToRenderPerBatch设为1,该参数控制每批次渲染的列表项数量,设为1会导致渲染效率极低,建议改为默认值10,可根据设备性能在5~15区间调整 - 移除写死的
refreshing={true}配置,该参数是下拉刷新状态标记,恒为true会导致FlatList持续处于刷新状态,占用多余性能 - 建议将
windowSize调整为默认值21,该值越大上下预加载内容越多,滑动流畅度越高,仅在设备性能极差时再调小该值
2. 替换数组查询为Set查询,降低查找时间复杂度
你当前使用selectedImagesId.includes(item.id)做选中判断,数组includes方法的时间复杂度为O(n),选中项较多时每次渲染都要遍历整个数组,改成用Set存储选中id,查询时间复杂度可降到O(1):
// 状态定义时用Set替代数组 const [selectedIdsSet, setSelectedIdsSet] = useState(new Set()) // 选中操作 const selectImageandId = (uri, id) => { setSelectedIdsSet(prev => new Set(prev).add(id)) // 保留原有其他逻辑 } // 取消选中操作 const removeImageandId = (index, id) => { setSelectedIdsSet(prev => { const newSet = new Set(prev) newSet.delete(id) return newSet }) // 保留原有其他逻辑 } // 渲染判断修改为 {selectedIdsSet.has(itemData.item.id) && <AntDesign name='checkcircle' ... />}
3. 用React.memo包裹RenderData组件,避免不必要的全量重渲染
当前只要选中列表变化,所有列表项都会全量重渲染,通过memo可以实现仅当前项的选中状态变化时才重渲染:
import { memo } from 'react' const RenderData = memo(({ itemData, isSelected, onToggleSelect }) => { return ( <View> <TouchableOpacity activeOpacity={0.8} style={{ width: width / 3.5, height: height / 7, padding: 2, }} onPress={() => onToggleSelect(itemData.item)} > <Image style={{ width: '100%', height: '100%' }} source={{ uri: itemData.item.uri }} resizeMode="cover" /> {isSelected && ( <AntDesign name='checkcircle' size={24} color='white' style={{ position: 'absolute', bottom: 5, right: 15 }} /> )} </TouchableOpacity> </View> ) }, (prevProps, nextProps) => { // 仅当选中状态变化或者item本身变化时才重渲染 return prevProps.isSelected === nextProps.isSelected && prevProps.itemData.item.id === nextProps.itemData.item.id }) // 父组件renderItem修改为 renderItem={(itemData) => ( <RenderData itemData={itemData} isSelected={selectedIdsSet.has(itemData.item.id)} onToggleSelect={handleToggleSelect} /> )}
4. 优化图片加载性能
- 建议替换原生Image组件为
react-native-fast-image,自带内存、磁盘缓存,避免重复加载图片占用资源 - 给Image设置
resizeMode="cover",避免大图解码消耗多余性能
5. 减少冗余数据
你当前同时维护selectedImages(存uri)和selectedImagesId(存id)两个数组,可合并为仅用一个Set存选中id,需要导出选中uri时再从原images数组过滤即可,减少数据操作的开销。
内容的提问来源于stack exchange,提问作者Rooban
相关产品推荐
相关产品推荐

