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
相关推荐
理想不理想v21 分钟前
前端项目性能优化(详细)
前端·性能优化
花追雨5 小时前
Android -- 双屏异显之方法一
android·双屏异显
小趴菜82275 小时前
安卓 自定义矢量图片控件 - 支持属性修改矢量图路径颜色
android
氤氲息5 小时前
Android v4和v7冲突
android
KdanMin5 小时前
高通Android 12 Launcher应用名称太长显示完整
android
chenjk45 小时前
Android不可擦除分区写文件恢复出厂设置,无法读写问题
android
袁震5 小时前
Android-Glide缓存机制
android·缓存·移动开发·glide
工程师老罗5 小时前
Android笔试面试题AI答之SQLite(2)
android·jvm·sqlite
User_undefined7 小时前
uniapp Native.js 调用安卓arr原生service
android·javascript·uni-app
安小牛7 小时前
android anr 处理
android