#我的鸿蒙开发手记#Flex布局性能优化 原创 精华

一路向北545
发布于 2025-5-6 16:47
浏览
0收藏

弹性布局(FLex)提供更加有效的方式对容器中的子元素进行排列、对齐和分配剩余空间。常用于页面头部导航栏的均匀分布、页面框架的搭建、多行数据的排列等。但Flex布局的不合理使用也会增加对性能的损耗,那么如何才能通过优化来减少性能的过度损耗呢?


一、应该考虑减少嵌套层级。

Flex布局如果嵌套太多层,可能会导致渲染变慢。可能的话,应该简化结构,用更少的容器。


二、列表渲染场景。

如果Flex布局用于长列表,比如用ForEach渲染很多项,没有做优化的话,滚动时可能会有卡顿。这时候应该使用列表项复用,比如List组件或者LazyForEach,只渲染可视区域内的项,减少内存和计算量。同时,给列表项设置固定尺寸,避免动态计算高度或宽度,这样滚动会更流畅。


List() {
  LazyForEach(dataSource, (item) => {
    ListItem() {
      Text(item.name).height(80) // 固定高度
    }
  })
}


三、避免不必要的重新布局。

Flex的某些属性会触发二次布局,这样会导致布局效率下降。

​​(1)flexGrow:设置父容器的剩余空间分配给此属性所在组件的比例。用于分配父组件的剩余空间。

  Flex({ wrap: FlexWrap.NoWrap }) {
        Text("A")
          .height(40)
          .backgroundColor(0xD2B48C)
          .width(100)
          .flexGrow(1)
        Text("B")
          .height(40)
          .width(100)
          .flexGrow(2)
          .backgroundColor(0xF5DEB3)
        Text("C")
          .height(40)
          .backgroundColor(Color.Red)
          .width(100)

      }.width(400)
      .height(100)
      .backgroundColor("#efefef")

#我的鸿蒙开发手记#Flex布局性能优化-鸿蒙开发者社区

#我的鸿蒙开发手记#Flex布局性能优化-鸿蒙开发者社区

如图父容器的宽度为400,A、B、C三个组件的宽度都为100,如果不设置flexGrow属性,会有100的剩余空间。当A的flexGrow为1,B的FlexGrow为3时,A、B会以1:3的比例来分剩余的100空间。A的宽度为100+1001/4=125,B的宽度为100+1003/4=175。再次分配空间会导致二次布局。

(2)flexShrink: 当父容器空间不足时,子元素的压缩比例


Flex({ wrap: FlexWrap.NoWrap }) {
        Text("A")
          .height(40)
          .backgroundColor(0xD2B48C)
          .width(200)
        Text("B")
          .height(40)
          .width(200)
          .flexShrink(1)
          .backgroundColor(0xF5DEB3)
        Text("C")
          .height(40)
          .backgroundColor(Color.Red)
          .width(200)
          .flexShrink(3)

      }.width(400)
      .height(100)
      .backgroundColor("#efefef")

#我的鸿蒙开发手记#Flex布局性能优化-鸿蒙开发者社区

#我的鸿蒙开发手记#Flex布局性能优化-鸿蒙开发者社区

如图父容器的宽度为400,A、B、C的宽度都为200,由于子组件宽度和大于父组件宽度,当不设置flexShrink时,ABC被平均压缩。当B的flexShrink为1,C的flexShrink为3时,B的宽度为200-2001/4=150,C的宽度为200-2003/4=50。

对不变的部分设置 ​flexShrink: 0​,防止压缩计算。


所以频繁修改 ​​flexGrow​​​、​​flexShrink​​ 或动态尺寸属性会导致重复布局计算。尽量为子组件设置固定尺寸(如 ​width: '100%'​ 或 ​height: 200​


// 不推荐:动态调整 flexGrow
@State growValue: number = 1;
Flex() {
  Text('Dynamic').flexGrow(this.growValue)
}

// 推荐:提前计算静态值


四、用visibility 替代 if/else​ 条件渲染,减少节点销毁/重建。


// 不推荐:频繁切换条件渲染
if (this.show) {
  Text('Content')
}

// 推荐:控制显隐
Text('Content').visibility(this.show ? Visibility.Visible : Visibility.None)


五、替代Flex容器的使用

优先使用Column/Row组件

Flex容器默认可能因子组件伸缩属性触发二次布局(如空间不足时调整flexShrink属性),而Column/Row组件在单轴布局中更高效,可避免不必要的二次计算


©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
标签
已于2025-5-9 16:58:53修改
收藏
回复
举报
回复
    相关推荐