提升Jetpack Compose 性能

186 篇文章 15 订阅

图片

如果你正在深入研究Jetpack Compose这个现代化的Android UI工具包,在本文中,将探讨一些增强Jetpack Compose性能的关键实践,着重介绍了一些应该做和不应该做的事情。通过实际的代码示例,展示如何通过对代码进行少量更改,显著提升应用程序的效率和性能。

1. 使用 @Immutable 和 @Stable 避免不必要的重组

默认情况下,Jetpack Compose认为类是不稳定的,如果它们包含可变变量(var)或可变集合,如ArrayList。这意味着Compose可能会频繁重新组合这些类,假设它们的状态可能已经发生了变化。但是通过使用这两个注解,可以避免这种错误行为。让我们来了解一下。

@Stable基本上是一个承诺,告诉Compose编译器这个对象可能会发生变化,但是只要它发生变化,Compose运行时就会被通知。看看下面的例子:

@Stable
class ProductListState(
  val products: List<Product>,
  val isLoading: Boolean
)

// 使用示例
@Composable
fun ShowProducts(
  modifier: Modifier = Modifier,
  productListState: ProductListState
) {
  LazyColumn(modifier = modifier) {
    items(productListState.products) {
      Text(text = it.name)
    }
  }
}

@Immutable用于标记完全不可变的类。一旦创建了这个类的对象,它内部的任何内容都不会改变,从而减少不必要的重新组合。注意:如果你向列表中添加或删除项,这个组合将永远不会被重新创建,因为你使用了"@Immutable"。

@Immutable
class ProductListState(
  val products: List<Product>,
)

@Composable
fun ShowProducts(
  modifier: Modifier = Modifier,
  productListState: ProductListState
) {
  LazyColumn(modifier = modifier) {
    items(productListState.products) {
      Text(text = it.name)
    }
  }
}

2. 使用无状态的组合函数

在Jetpack Compose中使用无状态的组合函数可以带来显著的性能优势。它们依赖于外部数据,在这些数据发生变化时才进行更新,从而减少不必要的重新组合。这也增强了可重用性和可测试性,使代码更加清晰和易于维护。

错误示例:

@Composable
fun MyOwnButtonWrong(item: String) {
  // 在组合函数内部管理状态 - 错误
  val buttonState = remember { mutableStateOf("Not Clicked!") }

  Button(onClick = { buttonState.value = "clicked!" }) {
    Text(text = buttonState.value)
  }
}

正确示例:

@Composable
fun MyOwnButton(item: String, onClick: () -> Unit) {
  Button(onClick = onClick) {
    Text(text = item)
  }
}

// 使用示例
@Composable
fun HomeScreen() {
  val buttonState = remember { mutableStateOf("Not Clicked!") }

  MyOwnButton(
    item = buttonState.value,
    onClick = { buttonState.value = "Clicked!" }
  )
}

3. 在动态列表中使用 'key' 参数

使用 'key' 参数有助于Compose理解哪些项发生了变化,哪些项保持不变或被删除,从而优化性能。这样可以避免对未更改的项进行不必要的重新组合,节省了大量资源,尤其是在大型或经常更改的列表中。让我们看看如何使用。

@Composable
fun DynamicListExample(items: List<Product>) {
  LazyColumn {
    items(
      items = items,
      key = { it.id }
    ) { item ->
      Text(text = item.name)
    }
  }
}

4. 避免不必要的副作用

在组合函数中避免不必要的副作用是提高应用程序性能的关键。有时我们必须在组合函数内部操作状态,但是当一个组合函数修改状态或执行超出其核心功能范围的操作时,就会产生不必要的副作用,可能导致不可预测的行为和意外的重新组合。看一个例子:

错误示例:

@Composable
fun ExempleSideEffect() {
  val state = remember { mutableStateOf(0) }

  // 副作用:在组合函数内部管理状态
  Button(onClick = { state.value++ }) {
    Text("Click here")
  }

  // 另一个副作用
  LaunchedEffect(key1 = state.value) {
    Log.d("Exemple", "State changes to ${state.value}")
  }
}

正确示例:

@Composable
fun ExempleCorrectSideEffect(onClickIncrement: () -> Unit, count: Int) {
  // 回调函数处理点击按钮
  Button(onClick = onClickIncrement) {
    Text("Click here")
  }

  // 显示计数器的值
  Text("Count: $count")
}

5. 使用惰性加载优化加载图片

在Jetpack Compose中使用惰性加载图片可以优化性能并提升用户体验:

  • • 仅在需要时加载图片,

  • • 减少内存使用,

  • • 改善应用程序的响应速度。

  • • Jetpack Compose 中的图像延迟加载可优化性能并增强用户体验:

  • • 与 Coil 和 Glide 等流行库集成,以实现高效的图像管理。

正确的:

@Composable
fun LazyLoadingWithCoil(url: String) {
    Image(
        painter = rememberImagePainter(
            data = url,
            builder = {
                crossfade(true)
            }
        ),
        contentDescription = null,
        modifier = Modifier.fillMaxWidth()
    )
}

错误的:

@Composable
fun LoadImageWithouLazyLoading(url: String) {
    val bitmap = loadImageBitmap(url) //hipotetic function that loads a bitmap
    Image(
        bitmap = bitmap,
        contentDescription = null,
        modifier = Modifier.fillMaxWidth()
    )
}

结论

在本文中,探讨了优化 Jetpack Compose 性能的几个关键策略。通过在开发过程中采用良好实践,提高 Android 应用程序的效率和响应能力。

转自:提升Jetpack Compose 性能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值