RN长列表(FlatList)性能优化的具体手段有哪些?

0 阅读2分钟

一、先理解 FlatList 为什么会卡

FlatList 本质是一个“虚拟列表(VirtualizedList) ”,它的性能瓶颈主要来自:

  1. JS 线程计算压力
  2. 频繁 re-render
  3. 布局计算(measure)
  4. Bridge 通信(JS ↔ Native)
  5. 内存占用过大

二、核心优化手段(必会)

1️⃣ 控制渲染窗口(最关键)

<FlatList
  initialNumToRender={10}
  maxToRenderPerBatch={10}
  windowSize={5}
/>

参数解释:

  • initialNumToRender:首屏渲染多少条
  • maxToRenderPerBatch:每批渲染数量
  • windowSize:渲染区域(单位:屏)

👉 推荐经验值:

initialNumToRender: 8~12
maxToRenderPerBatch: 8~16
windowSize: 5~10

📌 原理:减少一次性渲染数量,降低 JS 压力


2️⃣ 使用 getItemLayout(强烈推荐)

getItemLayout={(data, index) => ({
  length: ITEM_HEIGHT,
  offset: ITEM_HEIGHT * index,
  index,
})}

👉 适用于:item 高度固定

📌 作用:

  • 跳过 measure(布局测量)
  • scrollToIndex 更精准
  • 减少卡顿

👉 这是性能优化里收益最大之一


3️⃣ 避免不必要的 re-render(核心)

✅ 使用 React.memo

const Item = React.memo(({ item }) => {
  return <Text>{item.title}</Text>;
});

✅ keyExtractor 稳定

keyExtractor={(item) => item.id}

❌ 避免:

keyExtractor={(item, index) => index.toString()}

✅ renderItem 不要每次新建函数

const renderItem = useCallback(({ item }) => {
  return <Item item={item} />;
}, []);

4️⃣ 使用 shouldComponentUpdate / memo

复杂 item 必做:

export default React.memo(Item, (prev, next) => {
  return prev.item === next.item;
});

📌 避免整列表更新


5️⃣ 使用 removeClippedSubviews

<FlatList removeClippedSubviews />

📌 作用:

  • 移除屏幕外组件
  • 减少内存占用

⚠️ 注意:

  • 有时候会导致闪烁(尤其动画)

6️⃣ 减少 renderItem 复杂度

❌ 不要在 render 里做:

  • 复杂计算
  • JSON 处理
  • 大量逻辑判断

✅ 提前处理数据:

const processedData = useMemo(() => {
  return data.map(...)
}, [data]);

7️⃣ 避免 inline style

<View style={{ padding: 10 }} />

const styles = StyleSheet.create({
  item: { padding: 10 },
});

📌 减少重复创建对象


8️⃣ 分页 / 懒加载(必须)

onEndReached={loadMore}
onEndReachedThreshold={0.5}

📌 不要一次性加载几千条数据


9️⃣ 使用 ListHeaderComponent / ListFooterComponent

避免在外层包一层 ScrollView:

<ScrollView>
  <FlatList />
</ScrollView>

👉 直接用:

<FlatList
  ListHeaderComponent={<Header />}
  ListFooterComponent={<Footer />}
/>

🔟 控制更新频率(大数据场景)

extraData={selectedId}

📌 只在必要时触发更新


三、进阶优化(大厂级)

🚀 1. 使用 FlashList(性能碾压)

👉 Shopify 出的:

npm install @shopify/flash-list
import { FlashList } from "@shopify/flash-list";

📌 优势:

  • 更少掉帧
  • 更好的内存管理
  • 自动优化布局

👉 在大数据场景建议直接替换 FlatList


🚀 2. RecyclerListView(极致优化)

👉 更底层:

  • 完全自定义布局
  • 适合超大数据(万级)

但:
👉 使用复杂度高


🚀 3. 使用 InteractionManager

延迟非关键渲染:

InteractionManager.runAfterInteractions(() => {
  // 非关键任务
});

🚀 4. 避免频繁 setState

// ❌
setList([...list, newItem]);

// ✅ 批量更新

四、性能优化 checklist(实战必看)

你可以对照排查:

  • 是否使用 getItemLayout?
  • item 是否 memo?
  • renderItem 是否 useCallback?
  • key 是否稳定?
  • 是否分页加载?
  • 是否避免 inline object?
  • windowSize 是否合理?
  • 是否避免大对象传递?
  • 是否减少 bridge 通信?

五、给你一个推荐配置(通用模板)

<FlatList
  data={data}
  renderItem={renderItem}
  keyExtractor={(item) => item.id}
  initialNumToRender={10}
  maxToRenderPerBatch={10}
  windowSize={7}
  removeClippedSubviews
  getItemLayout={getItemLayout}
  onEndReached={loadMore}
/>

六、总结一句话

👉 FlatList 优化本质就是:

减少渲染数量 + 减少重渲染 + 减少计算 + 减少通信