更新部分区域时,Compose 是否会比 Android View 系统损失更多性能?

问题描述

我注意到Android上的Compose实际上是由AndroidComposeView实现的,当compose状态改变并且composable函数开始重构时,会从布局节点层调用AndroidComposeView.invalidate()(至少现在在master分支androidx 存储库)。

// For example: RenderNodeLayout

internal class RenderNodeLayer(
    val ownerView: AndroidComposeView,...
) : OwnedLayer {

    ...

    override fun invalidate() {
        if (!isDirty && !isDestroyed) {
            ownerView.invalidate()
            isDirty = true
        }
    }

    ...

}

这将使整个视图无效。如果 Compose 设计更大的 UI,例如通过函数 setContent() 设计整个 Activity,即使对 UI 进行微小更改也会使整个 Activity 内容失效。 Android 似乎只重绘了启用硬件加速时更改的界面部分,是否意味着 Compose 会损失更多性能?如果是这样,影响的代价有多大?

解决方法

Compose 中的重组起着重要作用。当 UI 的某些部分无效时,Compose 会尽最大努力仅重新组合需要更新的部分。这意味着它可能会跳过重新运行单个 Button 的可组合项,而不会执行 UI 树中其上方或下方的任何组合项。

此外,Compose 可以通过并行运行可组合函数来优化重组。这让 Compose 可以利用多个内核,并以较低的优先级运行不在屏幕上的可组合函数。