【问题标题】:Jetpack Compose Performance Issue that only occurs in multi module project仅在多模块项目中出现的 Jetpack Compose 性能问题
【发布时间】:2021-01-20 21:38:17
【问题描述】:

我在 Jetpack Compose 中开发了一个相当复杂的键盘布局。最初,布局工作正常,按下按键时动画运行非常流畅。不幸的是,由于事件的一些重新组合后,动画和一切都变得非常缓慢和滞后。 我尝试对 Jave 方法调用进行采样,但只能看到某些函数比平时花费的时间要长很多。

编辑: 我已经能够隔离问题。我发现性能问题只出现在多模块项目中。当我将 完全相同 撰写代码放在根 app 模块中时,问题就消失了。

我创建了一个重现该问题的项目:

如果你想在多模块项目中重现问题,你必须多次在类别之间切换,然后一切都变得非常滞后

注意:我知道 Jetpack Compose 仍处于 alpha 阶段,这个问题可能是 Jetpack Compose 中的一个错误。但我想确保这不是我的代码的错误或 Compose 的一般限制

【问题讨论】:

  • 该库声明它智能地“重组”,仅更新已更改的内容。我会检查您是否没有在可变状态下运行一些无限循环。要检测屏幕“卡顿”,请使用此处解释的正常机制 - developer.android.com/topic/performance/vitals/render
  • 如果您没有正确定义尺寸,xml 中的某些项目可能需要比平时更长的时间。对我来说,我曾经使用过 app:layout_constraintDimensionRatio="1:1" 导致应用程序滞后,因为它存在错误并且它正在重复计算尺寸。所以也要仔细检查xml文件
  • @Yannick 你能检查我的答案吗?如果您有任何反馈,请告诉我。谢谢
  • @Abdulrahman Abdelkader OP 询问 Jetpack Compose,这里没有 xml 内容。

标签: android android-jetpack-compose


【解决方案1】:

解决方案是使用 remember 可组合为 Keyboard @Composable 以防止在重新组合期间计算布局。

val refs: List<List<Pair<Key, ConstrainedLayoutReference>>> =
         remember {
             keyboard.map { row ->
                row.map {
                   it to createRef()
               }
          }
}

val modifier = remember { ... }

val modifierPressed = remember { ... }        

源码:https://github.com/dautovicharis/example_compose-keyboard-multimodule/commits/main

【讨论】:

  • 感谢您抽出宝贵时间调查此问题。您的解决方案适用于我提供的测试用例场景。不幸的是,它在我的真实应用程序中不起作用。我已经分叉了您的解决方案,并添加了在选择其中一项时(它显示不同的键标签)切换键盘的功能。你可以在这里找到它:github.com/THEAccess/…。另外,也许你能解释一下为什么这个问题只出现在多模块项目中?
  • 我发现的唯一解决方案是通过keyboardUniqueID 将所有ConstrainedLayoutReferences 保留在HashMap 中。代码:github.com/dautovicharis/…。这是我第一次使用 Android @Composable - 我不知道为什么这只发生在多模块项目中。
【解决方案2】:

总的来说,它是一个 Jetpack Compose 应用程序并没有什么特别之处。您可以使用 Android Studio 中的 CPU profilerrecord a trace 更具体地查看您的应用程序中发生的情况。如果不看代码,很难知道是什么导致某些函数比平时花费更长的时间,但实际上可能是它们被重复调用(采样方法无法区分)。

您还可以在@Composable 函数中放置打印语句或断点。确保函数在您不期望它们时不会被调用(重组)。如果是,您需要调查导致他们再次被调用的原因。

【讨论】:

  • 我已经能够找出性能问题的原因并添加了一个可重现的示例 repo
【解决方案3】:

LazyColumnLazyVerticalGrid 遇到了同样的问题(并且我有一个单模块项目),它们非常缓慢和滞后,以至于我对 Jetpack Compose 的承诺失去了信心。

然而,事实证明这完全是因为 Jetpack Compose 在 debug 构建类型中的内部工作,因为在后台进行了很多工作以允许直接编辑文字和调试可组合项。

解决方案基本上是构建应用程序的发布版本。这会优化代码并禁用任何调试功能,使我的应用程序运行无延迟、流畅、快速。

感谢reddit comment 提出这个建议。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-29
    • 1970-01-01
    • 2014-06-02
    • 1970-01-01
    • 1970-01-01
    • 2020-08-16
    • 2021-10-28
    相关资源
    最近更新 更多