布局优化
造成布局性能问题的原因
- 布局嵌套层级过多,或使用了不恰当的布局组件,会使布局阶段的时间变长,导致用户遇到掉帧、卡顿、响应慢的问题
- 性能差的布局,还可能使用过多的内存资源,导致占用过多的内存,使设备性能下降
- 分两个阶段
- 测算(Measure):负责确定组件对象的测量宽/高
- 布局(Layout):确定组件的最终宽/高和四个顶点的位置
布局性能优化的方法
- 一:减少节点数
- 移除冗余的节点
- 用合适的布局组件,减少节点嵌套,从而减少节点数
- 二:减少测算布局耗时
- 合理控制元素的显示与隐藏
- 不需要经常改变其显示性的,使用 if else
- 需要经常改变的,使用 visibility()
- 给定组件宽高方面,性能对比:
- 限制为固定宽高 (最优)
- 不限定宽高 (中等)
- 限制为百分比的 (最差)
- 布局组件基础性能
- Row / Column
- Stack
- RelativeContanier
- Flex
- Grid
长列表优化
使用懒加载
LazyForEach() 组件
@Component
export struct DiscoverView {
@State dataSource: LazyDataSource = new LazyDataSource();
build() {
Column() {
List({ space: CommonConstants.SPACE_12 }) {
LazyForEach(this.dataSource, (item: LearningResource) => {
ListItem() {
ArticleCardView()
}
}, (item: LearningResource) => item.id)
}
}
}
}
缓存列表项
配合 LazyForEach() 组件,通过预加载数据,提升列表的滑动体验
@Component Struct MyComponent { build () { List () { LazyForeEach () { ... } .cachedCount(n/2) } } }
组件复用
重复使用创建过并缓存的组件对象,降低相同组件短时间内频繁创建销毁的开销
@Component
export struct DiscoverView {
private dataSource: ArticleListData = new ArticleListData();
......
build() {
List() {
LazyForEach(this.dataSource, (item: LearningResource) => {
ListItem() {
ArticleCardView()
// 3. 设置 reuseId
.reuseId('article')
}, (item: LearningResource) => item.id)
}
}.cachedCount(3);
}
}
@Component
@Reusable // 1. 使用 @Reusable 装饰器
export struct ArticleCardView {
@Prop isCollected: boolean = false;
@Prop isLiked: boolean = false;
@Prop articleItem: LearningResource = new LearningResource();
onCollected?: () => void;
onLiked?: () => void;
// 2. 定义组件复用的方式
aboutToReuse(params: Record<string, Object>): void {
this.onCollected = params.onCollected as () => void;
this.onLiked = params.onLiked as () => void;
}
build() {
...
}
}
布局优化
使用扁平化布局,减少视图嵌套层级与组件数 同上面的 布局优化
系列文章
参考资料
写在最后
- 不是教程,只是学习记录
- 包含了一些自己的理解,一边学一边写的,难免有不对的地方
- 写出来希望能与大家探讨,看到有错误的地方,望大家指正~