gpt4 book ai didi

react-native - 找出性能问题

转载 作者:行者123 更新时间:2023-12-03 16:25:04 24 4
gpt4 key购买 nike

在过去的几天里,我一直在解决我创建的应用程序中 FlatList 的性能问题。

FlatList 由静态标题和 x 行组成。在测量的情况下,有 62 行,每行由 4 个组件组成——其中一个被使用了 4 次,总共有 7 个行单元格。此列表的每个单元格都是 TouchableNativeFeedback 或 TouchableOpacity(出于测试目的,那些已将 () => null 附加到 onPress。在几个级别(列表容器、行、单个单元格)上使用了 shouldComponentUpdate,我认为渲染性能对于这种情况来说已经足够好了的列表。

对于一致的测量,我使用了 initialNumToRender={data.length} ,所以整个列表一次呈现。使用按钮呈现列表,数据加载不是我测量的一部分 - 它已预加载到组件本地状态。

根据附加的 Chrome Performance Profile JS 线程需要 1.33s 来渲染组件。我使用 CPU 减速 x6 来更准确地模拟 Android 设备。

然而,列表显示在设备上大约需要 15 秒标记,因此从按下按钮到显示列表的实际渲染需要超过 14 秒!

我想弄清楚的是 JS 渲染组件和实际显示在屏幕上的组件之间发生了什么,因为设备是
整个那段时间 react 迟钝。每个触摸事件都会被注册,但只有在列表最终出现在屏幕上时才会播放。

我已经附加了来自 chrome 开发工具的跟踪,使用 android systrace 工具获取的 systrace 和来自 android profiler 的屏幕(遗憾的是我找不到导出后者的选项)。

跟踪几乎同时运行——顺序是 systrace、android profiler、chrome 开发工具。

我应该采取哪些步骤来帮助我了解应用程序卡住时发生的情况?

Simple reproduction application (code in src.js, first commit)

Chrome Performance Profile
Chrome Performance Profile

Systrace HTML
Systrace HTML

安卓探查器
Android Profiler

最佳答案

看着source code you posted ,我不认为这是一个 React 渲染问题。

问题是您在 render 中做的工作太多了。方法和您在渲染过程中调用的辅助方法。

每次调用.filter , .forEach.map在一个数组上,整个列表被迭代 n次。当您为 m 执行此操作时组件,计算复杂度为 O(n * m) .

例如,这是 TransportPaymentsListItem渲染方法:

/**
* Render table row
*/
render() {
const {
chargeMember,
obligatoryChargeNames,
sendPayment,
eventMainNavigation
} = this.props;

/**
* Filters obligatory and obligatory_paid_in_system charges for ChargeMember
*/
const obligatoryChargesWithSys = this.props.chargeMember.membership_charges.filter(
membershipCharge =>
membershipCharge.type === "obligatory" ||
membershipCharge.type === "obligatory_paid_in_system"
);

/**
* Filters obligatory charges for ChargeMember
*/
const obligatoryCharges = obligatoryChargesWithSys.filter(
membershipCharge => membershipCharge.type === "obligatory"
);

/**
* Filters obligatory adjustments for ChargeMember
*/
const obligatoryAdjustments = this.props.chargeMember.membership_charges.filter(
membershipCharge =>
membershipCharge.type === "optional" &&
membershipCharge.obligatory === true
);

/**
* Filters obligatory trainings for ChargeMember
*/
const obligatoryTrainings = this.props.chargeMember.membership_charges.filter(
membershipCharge =>
membershipCharge.type === "training" &&
membershipCharge.obligatory === true
);

/**
* Filters paid obligatory adjustments for ChargeMember
*/
const payedObligatoryTrainings = obligatoryTrainings.filter(
obligatoryTraining =>
obligatoryTraining.price.amount ===
obligatoryTraining.amount_paid.amount
);

// This one does a .forEach as well...
const sums = this.calculatedSums(obligatoryCharges);

// Actually render...
return (

在示例代码中有 11 个这样的迭代器调用。对于您使用的 62 行数据集,数组迭代器被称为总计 4216 次!即使每个迭代器都是非常简单的比较,简单地遍历所有这些列表也太慢并且阻塞了主 JS 线程。

为了解决这个问题,您应该在组件链中将状态转换提升到更高的位置,这样您就可以只进行一次迭代并构建一个 View 模型,您可以将组件树向下传递并以声明方式呈现,而无需额外的工作。

关于react-native - 找出性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48626555/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com