本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
一、布局节点优化的核心原理
1. 节点过多的问题
- 测量/布局耗时:每个节点需要经历
Measure → Layout → Draw
流程 - 内存占用:每个节点约占用0.5~2KB内存
- 示例对比:
// 低效布局(嵌套6层)
Column() {
Row() {
Column() {
Row() {
Column() {
Text('Hello')
}
}
}
}
}
// 高效布局(扁平化)
Flex({ direction: FlexDirection.Column }) {
Text('Hello')
}
2. 优化目标
- 节点深度:控制在4层以内
- 冗余节点:消除无实际作用的容器
二、基础优化方案
1. 使用高效布局容器
容器类型 | 适用场景 | 优化优势 |
---|---|---|
Flex | 线性排列 | 计算复杂度O(n) |
Grid | 网格布局 | 支持虚拟化 |
RelativeContainer | 相对定位 | 减少嵌套层级 |
示例:替换复杂嵌套
// 优化前:嵌套Column+Row实现居中
Column() {
Row() {
Text('Hello').alignSelf(VerticalAlign.Center)
}.width('100%')
}
// 优化后:使用Flex
Flex({ justifyContent: FlexAlign.Center }) {
Text('Hello')
}.width('100%')
2. 组件提取与复用
问题代码:
Column() {
// 重复结构
Row() {
Icon($r('app.media.icon'))
Text('Item 1')
}
Row() {
Icon($r('app.media.icon'))
Text('Item 2')
}
}
优化方案:
@Component
struct ListItem {
@Prop text: string
build() {
Row() {
Icon($r('app.media.icon'))
Text(this.text)
}
}
}
Column() {
ListItem({ text: 'Item 1' })
ListItem({ text: 'Item 2' })
}
备注:@Builder不涉及生命周期,在自定义组件大量嵌套的场景中,更加轻量级的@Builder在性能方面更加出色。因此,当自定义组件不涉及到状态变量和自定义生命周期时,可以优先使用@Builder替换自定义组件,提升性能。
三、中级优化方案
1. 条件渲染优化
错误示范:
Column() {
if (show) {
Column() { // 冗余容器
Content()
}
}
}
正确做法:
Column() {
if (show) {
Content() // 直接渲染
}
}
2. 列表性能优化
关键配置:
List() {
LazyForEach(data, item => {
ListItem({ item })
}, item => item.id)
}
.width('100%')
.cachedCount(10) // 预加载项数
.edgeEffect(EdgeEffect.None) // 禁用边缘效果
四、高级优化方案
1. 自定义绘制替代复杂布局
场景:需要实现特殊效果的布局(如弧形标题)
@Component
struct ArcHeader {
build() {
Canvas() {
// 直接绘制替代多层嵌套
Path()
.arc({ x: 0, y: 0, radius: 100 })
.fill('#FFF')
Text('Title').position({ x: 50, y: 20 })
}
}
}
2. 动态布局计算
场景:响应式布局中避免冗余节点
@Entry
@Component
struct ResponsiveLayout {
@State windowWidth: number = 360
aboutToAppear() {
window.on('windowSizeChange', (size) => {
this.windowWidth = size.width
})
}
build() {
// 根据宽度动态选择布局方式
(this.windowWidth > 600 ? this.buildWide() : this.buildCompact())
}
buildWide() {
Flex({ wrap: FlexWrap.Wrap }) {
ForEach(this.data, item => {
ItemCard({ item }).width('50%')
})
}
}
buildCompact() {
Column() {
ForEach(this.data, item => {
ItemCard({ item })
})
}
}
}
五、工具链支持
1. UI Inspector
- 功能:可视化查看节点层级
- 操作:
- 在DevEco Studio中启动
Previewer
- 打开
Tools → UI Inspector
- 查看
Node Tree
面板
- 在DevEco Studio中启动
2. 性能分析命令
# 查看布局耗时
adb shell dumpsys gfxinfo <package_name>
# 节点数统计
adb shell dumpsys activity top | grep -i view
六、优化检查表
- 使用
Flex/Grid
替代嵌套 - 节点深度控制在4层内
- 列表配置
cachedCount
- 定期用UI Inspector审查
- 复杂效果优先考虑Canvas绘制