摘要:在 React Native项目中,列表(FlatList / SectionList / VirtualizedList) 是最常见的组件之一。
在 React Native项目中,列表(FlatList / SectionList / VirtualizedList) 是最常见的组件之一。
但随着数据量增大、item UI 复杂度提升,列表性能问题也逐渐凸显,比如:
首屏白屏
滑动掉帧
内存占用过高
无意义的重复渲染
今天我结合实际经验,总结一份 React Native 列表优化实践手册,帮助大家把列表从“卡顿”调优到“丝滑”。
1. 基础配置优化
initialNumToRender控制初始渲染条数,避免一次性渲染过多。一般根据首屏可见区合理设置,比如initialNumToRender={10}。
windowSize设置可视窗口外的缓冲区渲染范围。默认值 21(前后各 10 屏),可根据列表密度下调到 5~10,减少内存占用。
maxToRenderPerBatch限制一次批量渲染的数量,避免卡顿。推荐设置为5~10。
updateCellsBatchingPeriod控制每批次渲染的时间间隔(毫秒),一般设16~50,避免掉帧。
2.keyExtractor& 稳定 key使用稳定唯一的 key(如 id),不要用index。
避免 key 频繁变化,否则会触发额外渲染。
3. Item 渲染优化纯组件将 item 封装为React.memo或PureComponent,配合props的稳定性,避免无意义的重渲染。
const MovieItem = React.memo(({ title, cover }: {title: string; cover: string}) => {return ({title} )})getItemLayout如果列表 item 高度固定,使用getItemLayout直接计算 offset,避免动态测量:
getItemLayout={(data, index) => ({length: ITEM_HEIGHT,offset: ITEM_HEIGHT * index,index,})}图片优化
使用react-native-fast-image,支持缓存、占位图。
图片尺寸固定,避免 reflow。
4. 避免匿名函数 & 内联对象在renderItem里不要频繁定义函数或样式:
// ❌ 坏例子renderItem={({item}) => handleClick(item)} />} // ✅ 好例子const renderItem = useCallback(({item}) => (handleClick(item)} /> ), [handleClick])把StyleSheet.create放在组件外,避免重复创建。
5. 分页 & 下拉刷新优化分页加载使用onEndReached+onEndReachedThreshold,并加节流/防抖,避免重复请求。
下拉刷新合理使用refreshing状态,避免不必要的全局重渲染。
6. 状态管理 & 渲染隔离列表 item 的局部状态,不要放在全局 Redux/Context,避免全量刷新。
可以使用zustand或jotai这种原子化状态管理,或者局部useState。
7. Skeleton & 占位优化使用骨架屏(Skeleton)代替白屏,提高感知性能。
可以基于react-native-skeleton-placeholder实现。
8. 动画与交互优化使用react-native-reanimated+react-native-gesture-handler做交互/滑动动画,避免 JS thread 卡顿。
如果需要复杂的 UI 滚动联动(吸顶、tab 切换),推荐FlashList或RecyclerListView。
9. 第三方库选择FlashList (Shopify 出品)基于底层优化,支持数千条数据流畅渲染,性能远超 FlatList。
import { FlashList } from '@shopify/flash-list';data={movies} renderItem={renderItem} estimatedItemSize={100} />RecyclerListView更极致的虚拟化,适合超大数据集。
10. Debug & 性能监控开启性能监控:UI → Performance Monitor查看 FPS、JS 线程负载。
使用why-did-you-render检查无意义重渲染。
Android 端可用Systrace/Flipper追踪掉帧原因。
总结:最后,祝大家双节快乐!
来源:万腾教育