优化 FlatList 配置
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
术语表
-
VirtualizedList:
FlatList的底层组件(React Native 对Virtual List概念的实现) -
内存消耗 (Memory consumption): 列表信息在内存中的存储量,过高可能导致应用崩溃
-
响应性 (Responsiveness): 应用响应交互的能力。例如低响应性表现为触摸组件后出现延迟响应,而非预期的即时反馈
-
空白区域 (Blank areas): 当
VirtualizedList渲染速度不足时,列表会出现未渲染组件形成的空白区块 -
视口 (Viewport): 实际渲染为像素的可见内容区域
-
窗口 (Window): 组件应被挂载的区域,通常远大于视口范围
属性
以下参数可帮助提升 FlatList 性能:
removeClippedSubviews
| Type | Default |
|---|---|
| Boolean | true on Android, otherwise false |
若为 true,位于视口之外的视图会自动从原生视图层级中分离。
优点: 通过排除视口外视图的原生渲染和绘制遍历,减少主线程耗时,降低掉帧风险
缺点: 该实现可能存在缺陷(尤其在 iOS 平台),例如内容缺失(常见于复杂变换/绝对定位场景)。注意这不会显著节省内存,因为视图仅被分离而非释放
maxToRenderPerBatch
| Type | Default |
|---|---|
| Number | 10 |
可通过 FlatList 传递的 VirtualizedList 参数,控制每次滚动时渲染的批次项目数量
优点: 增大数值可减少滚动时的视觉空白区域(提升填充率)
缺点: 每批次项目增多可能导致 JavaScript 执行时间过长,阻塞点击等事件处理,影响响应性
updateCellsBatchingPeriod
| Type | Default |
|---|---|
| Number | 50 |
maxToRenderPerBatch 控制每批渲染数量,而设置 updateCellsBatchingPeriod 则告诉你的 VirtualizedList 批次渲染间的毫秒级延迟(决定窗口化项目的渲染频率)
优点: 结合此参数与 maxToRenderPerBatch 可实现灵活配置,例如低频次渲染更多项目或高频次渲染较少项目
缺点: 低频批次可能导致空白区域,高频批次可能引发响应性问题
initialNumToRender
| Type | Default |
|---|---|
| Number | 10 |
初始渲染的项目数量
优点: 精确定义覆盖各类设备屏幕所需数量,可大幅提升初始渲染性能
缺点: 将 initialNumToRender 设置过低可能导致空白区域(尤其在初始渲染无法覆盖视口时)
windowSize
| Type | Default |
|---|---|
| Number | 21 |
数值单位 1 等同于视口高度,默认值 21(上方 10 视口 + 下方 10 视口 + 中间 1 视口)
优点: 增大 windowSize 可降低滚动空白风险,减小 windowSize 则减少同时挂载项目以节省内存
缺点: windowSize 越大内存消耗越高,windowSize 越小出现空白区域的概率越大
列表项
以下是一些关于列表项组件的优化技巧。它们是列表的核心,因此需要保持高效。
使用基础组件
组件越复杂,渲染速度越慢。尽量避免在列表项中嵌套过多逻辑和组件层级。如果需要在应用中复用该列表项组件,建议为长列表专门创建极简化的组件,尽可能减少逻辑处理和嵌套层级。
使用轻量组件
组件越重,渲染越慢。避免使用大尺寸图片(列表项中应使用裁剪版或缩略图,尺寸越小越好)。与设计团队沟通,在列表中尽量精简特效、交互动效和信息展示,这些内容可移至详情页呈现。
使用 memo()
React.memo() 创建的记忆化组件仅在传入属性变更时才会重新渲染。我们可以利用该函数优化 FlatList 中的组件性能。
import React, {memo} from 'react';
import {View, Text} from 'react-native';
const MyListItem = memo(
({title}: {title: string}) => (
<View>
<Text>{title}</Text>
</View>
),
(prevProps, nextProps) => {
return prevProps.title === nextProps.title;
},
);
export default MyListItem;
在下方示例中,我们设定了 MyListItem 组件仅在 title 属性变更时重新渲染。通过向 React.memo() 传入比较函数作为第二个参数,可确保组件仅在指定属性变化时更新。若比较函数返回 true,组件将跳过渲染。
使用缓存的优化图像
您可以使用社区包(例如 Dream11 的 @d11/react-native-fast-image)获取更高性能的图片。列表中的每张图片都是 new Image() 实例,图片加载越快到达 loaded 钩子,JavaScript 线程就能越快恢复空闲。
使用 getItemLayout
当所有列表项具有相同高度(或水平列表的宽度)时,提供 getItemLayout 属性可免除 FlatList 的异步布局计算需求,这是非常推荐的优化手段。
若组件尺寸动态变化又亟需性能提升,可考虑与设计团队沟通是否接受优化导向的重新设计。
使用 keyExtractor 或 key
为 FlatList 设置 keyExtractor 属性,该属性用于缓存机制并作为 React 的 key 追踪项目重排序。
也可直接在列表项组件中使用 key 属性。
避免在 renderItem 中使用匿名函数
函数式组件中,请将 renderItem 函数移至 JSX 返回结构外部,并用 useCallback 钩子包裹以避免每次渲染时重新创建。
类组件中,将 renderItem 函数移出 render 方法,防止每次调用 render 时重新创建函数。
const renderItem = useCallback(({item}) => (
<View key={item.key}>
<Text>{item.title}</Text>
</View>
), []);
return (
// ...
<FlatList data={items} renderItem={renderItem} />;
// ...
);