react-native - React Native SectionList 性能问题:滚动 React Native SectionList 时 JS 帧率极低
问题描述
对于简单的单元格渲染(单个文本标签),滚动 SectionList 会导致不合理的低 JS 帧率下降(~30),如果单元格内容更复杂(每个单元格中的多个文本标签将导致单个数字 JS 帧),情况会变得更糟利率下降)。
当用户在滚动后点击任何东西时,低 JS 帧速率所体现的用户面临的问题是响应时间非常慢(可能延迟约 5 秒)。
如果您更喜欢自己引导它,或者在不去 GitHub 的情况下在此处查看它,这里是整个源代码(来自该 repo 的 App.tsx 文件;61 行):
import React from "react"
import { FlatList, SectionList, Text, View } from "react-native"
const listSize = 10_000
const listItems: string[] = Array.from(
Array(listSize).keys(),
).map((key: number) => key.toString())
const alwaysMemoize = () => true
const ListItem = React.memo(
({ title }: { title: string }) => (
<View style={{ height: 80 }}>
<Text style={{ width: "100%", textAlign: "center" }}>{title}</Text>
</View>
),
alwaysMemoize,
)
const flatListColor = "green"
const flatListItems = listItems
const sectionListColor = "blue"
const sectionListItems = listItems.map(listItem => ({
title: listItem,
data: [listItem],
}))
const approximateStatusBarHeight = 40
const App = () => {
const renderItem = React.useCallback(
({ item }: { item: string }) => <ListItem title={item} />,
[],
)
const renderSectionHeader = React.useCallback(
({ section: { title } }: { section: { title: string } }) => (
<ListItem title={title + " section header"} />
),
[],
)
return (
<View style={{ flex: 1, paddingTop: approximateStatusBarHeight }}>
<FlatList
style={{ flex: 1, backgroundColor: flatListColor }}
data={flatListItems}
renderItem={renderItem}
keyExtractor={item => item}
/>
<SectionList
style={{ flex: 1, backgroundColor: sectionListColor }}
sections={sectionListItems}
renderItem={renderItem}
renderSectionHeader={renderSectionHeader}
keyExtractor={item => item}
/>
</View>
)
}
export default App
我是否错过了一些性能优化/我做错了什么?或者这是 React Native 的预期表现?
另一个问题作为旁注:如果我没有将每个单元格的高度设置为相当高的高度(例如上面示例中的 80),而只是让高度调整为包含文本的高度(我相信是 14pt) ,两种类型的列表的 JS 帧率下降变得非常糟糕;20 JS 帧或更少。
我还要在这里指出,屏幕截图中显示的性能测试是在 iPhone 13 mini 上完成的。
解决方案
推荐阅读
- c++ - 在 C++ 中初始化向量
- php - 如何从数字中删除数字并将其替换为 PHP 中的字母?
- javascript - 在 javascript 中,我是否可以返回我悬停的任何 DOM 元素的元素?
- html - 在 CSS 中使用 display flex
- javascript - 显示两部手机之间位置的简单网络应用程序
- oauth-2.0 - 客户端应用程序中的 IdentityServer4 无效范围
- angular - 何时在 Angular 中使用模板驱动和响应式表单
- python - 在 Keras (2.4.3) 和 Tensorflow (2.4.1) 中使用 NumPy 数组
- ios - 如何对 UIApplication 扩展进行单元测试
- webpack - 升级到 Webpack 5 后出现“此源的内容和地图不可用”错误