ArkUI进阶-性能优化

ArkUI进阶-性能优化

布局性能优化

基本布局流程

在ArkUI的布局过程中,应用侧会根据前端UI描述创建后端的页面节点树,包含处理UI组件属性更新,布局测算,事件处理等逻辑。

例如上述布局:

  1. 应用会根据我们的代码,创建对应的node节点树,其中,Custom Node表示自定义组件节点,Frame Node节点表示系统组件节点。
  2. 在这个过程中,UI线程会对每个元素进行测算measure和布局lauout,来确定具体的位置和大小,measure阶段负责确定组件的测量宽高,也就是该组件元素占用的屏幕大小,layout阶段会确定最终宽高和四个顶点的位置。
  3. 根据页面节点树,生成当前界面描述数据结构--渲染树。渲染树由RenderNode渲染节点组成,描述了具体元素在屏幕上的布局信息,包含大小、位置以及一些其他属性。
  4. 渲染服务的渲染线程会根据渲染树的信息执行相应的绘制工作。

在布局阶段中,如果视图嵌套层级较深,或者页面节点过多,会导致在Measure和layout过程中,通过遍历测量组件大小和边界的时间过长。所以布局性能优化,可以从减少节点数或者优化布局测算时间方面来考虑。

精简节点数

首先我们先看一下相同数量节点嵌套和平铺的情况下,对性能的影响,通过使用IDE的profiler工具进行抓取,可以得知:

从上边我们可以看出,在相同组件、相同数量的情况下,嵌套和平铺对性能的影响差距不是很大,主要影响性能的还是节点数量,所以我们在进行布局的时候,应该尽量减少参与布局的节点数,来减少布局的性能消耗。

主要有两个优化方向:

  1. 移除冗余节点。
  2. 使用扁平化布局,减少层级嵌套,如RelativeContainerGrid等。

合理控制元素的隐藏与显示

在ArkUI中,控制元素隐藏和显示,一般有两种方式,使用条件语句控制,或者使用visibility属性来控制。

我们来对比使用条件渲染语句和使用visibility属性来控制时,measure和layout耗时区别:

首次渲染:

我们可以看到,使用条件渲染语句时,当条件为false时,对应组件不参与measure和layout阶段。使用visibility属性进行控制的时候,无论组件是否显示,都会参与measure阶段,如果visibility为none,那么组件不参与layout阶段。

切换显示

我们可以看到,切换显示状态的时候,使用条件渲染语句,会根据条件来判断组件是否创建,切换过程会出现较大的性能消耗,且每次切换消耗相同。使用visibility的时候,性能消耗要小很多。

综上所述,在控制组件的显示与隐藏时,我们可以遵循以下原则:

  • 对性能要求较高,且会频繁切换显示与隐藏的情况下,使用visibility属性进行控制。
  • 组件创建性能消耗较大,且初始状态下不可见,并且不会频繁切换的情况下,使用条件渲染语句进行控制。

给定组件的宽高

在ArkUI中,我们给组件设置宽高的方式,一般分为三种:设置固定值、百分比宽高、不设置宽高。

我们对比三种情况下的measure和layout的耗时

初次加载时,三种情况消耗差距不大,原因是初次加载的时候,所有的组件都参与了measure和layout过程。

在重绘的过程中,我们可以看到,给定宽高的组件,所消耗的性能明显小于其他两种方式,原因是修改宽高触发重绘的情况下, 给定内部组件宽高时,内部组件可以重用初次measure和layout数据,不设置宽高和百分比宽高的,由于父容器宽高发生了变化,所以需要参与measure和layout过程。

使用推荐的布局组件

越是复杂的布局,measure和layout的过程越是耗时,比如grid组件就会比row组件耗时,但是如果使用grid组件,可以明显减少页面的节点数量或者是嵌套层级数量,那么此时所节省的性能会明显优于grid组件多消耗的性能。

长列表加载性能优化

长列表优化概述

针对长列表加载场景,对列表渲染速度、页面滑动帧率、内存占用大小等方面进行优化,主要有以下几个方面

  • 懒加载:提供列表数据按需加载的能力,解决一次性加载列表项耗时过长,占用过多资源的问题,提升页面加载速度。
  • 缓存列表项:提供屏幕可视区域外列表缓存长度的自定义调节能力,配合懒加载使用,缓存页面数据,预加载页面外列表项,提升列表滑动体验。
  • 组件复用:提供可复用组件对象的缓存资源池,通过重复使用已经创建并缓存的组件对象,降低相同组件短时间内频繁创建和销毁的消耗,提升渲染效率。
  • 布局优化:使用扁平布局,减少视图嵌套层级和节点数,提升渲染效率。

懒加载

当列表数据量较小且布局较为简单的时候,我们可以使用ForEach渲染语句。

当列表数据量较大时,使用lazyForEach渲染语句实现懒加载的效果。

使用lazyForEach渲染语句时,最小可以做到仅加载渲染屏幕当前显示的列表项。

缓存列表项

我们使用了lazyForEach懒加载时,默认只会渲染当前屏幕显示的列表项,那么当我们快速滑动的时候,就会出现白块的现象。

lazyForEach可以通过设置cachedCount来缓存或预加载一定数量的列表项,比如当前屏幕最大可以显示5条,cachedCount为3,那么此时挂载在组件树上的列表项,最多可以是11条。

组件复用

  1. 在item列表项的自定义组件头部添加@Reusable装饰器,标识该组件拥有复用的能力。
  2. 实现可复用自定义组件的生命周期aboutToReuse方法,也就是我们的数据填充逻辑。
  3. 在ListItem组件上设置可复用组件的ReuseId
相关推荐
zhangjr05751 小时前
【HarmonyOS Next】鸿蒙实用装饰器一览(一)
前端·harmonyos·arkts
NotesChapter1 小时前
Android吸顶效果,并有着ViewPager左右切换
android
_祝你今天愉快2 小时前
分析android :The binary version of its metadata is 1.8.0, expected version is 1.5.
android
暮志未晚Webgl2 小时前
109. UE5 GAS RPG 实现检查点的存档功能
android·java·ue5
麦田里的守望者江3 小时前
KMP 中的 expect 和 actual 声明
android·ios·kotlin
Dnelic-3 小时前
解决 Android 单元测试 No tests found for given includes:
android·junit·单元测试·问题记录·自学笔记
佛系小嘟嘟3 小时前
Android Studio不显示需要的tag日志解决办法《All logs entries are hidden by the filter》
android·ide·android studio
mariokkm4 小时前
Django一分钟:django中收集关联对象关联数据的方法
android·django·sqlite
长亭外的少年4 小时前
如何查看 Android 项目的依赖结构树
android
深海呐6 小时前
Android 从本地选择视频,用APP播放或进行其他处理
android·音视频·从本地选择视频,用app播放·从本地选择视频,并拿到信息·跳转到本地视频列表