【最新鸿蒙应用开发】——优化之页面优化、合理状态管理、日志优化、工具使用

154 阅读9分钟

本文正在参加华为鸿蒙有奖征文征文活动

优化手段之页面优化、合理状态管理、日志优化、工具使用

一、页面性能内存优化

页面性能优化,主要在少嵌套,减少动态渲染的频率。在进行页面布局开发时,应该去除冗余的布局嵌套;扁平化减少中间嵌套的层级;另外还需要结合开发场景使用一些高性能的高级组件构建复杂布局,例如Flex、Grid、WaterFlow、RelativeContainer、绝对布局、自定义布局等,达到优化页面性能,减少页面内存,提高页面性能的效果。

1、精简节点数:
  • 移除冗余节点,

    • 比如有些效果,使用一个节点可以实现的,不要用多个节点
    • 例如:一断文字,有间隔,完全可以使用一个Text,中间添加一些空格
  • 扁平化减少中间的嵌套层级,使总的组件节点数减少。

    • 使用更高级的布局使得页面变得更加扁平化
    • 例如:RelativeContainer通过相对布局实现扁平化,不用Row嵌套Column,多层嵌套
2、使用一些高性能的组件构建复杂布局
  1. 使用row/column+layoutweight代替flex容器使用,由于Flex本身会带来的二次布局而影响性能。
  2. scroll嵌套list/grid容器时,要设置容器的宽高。
  3. 数组数据渲染尽量使用lazyforeach渲染item
  4. 组件的显隐设置,要使用if语句来判断,避免使用visibility
  5. list/grid容器要根据具体场景来使用cachecount,避免卡顿
  • 补充:什么是LazyForeach(懒加载)? LazyForEach懒加载从提供的数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。当LazyForEach在滚动容器中使用时,框架会根据滚动容器可视区域按需创建组件,当组件划出可视区域外时,框架会进行组件销毁回收以降低内存占用。LazyForEach提供列表数据按需加载能力,解决一次性加载长列表数据耗时长、占用过多资源的问题,可以提升页面响应速度。

二、合理管理状态变量

应该合理地使用状态变量,精准控制组件的更新范围,控制状态变量关联组件数量上限,控制对象级状态变量的成员变量关联组件数,减少系统的组件渲染负载,提升应用流畅度。

1、 精准控制组件的更新范围

在复杂页面开发的场景下,精准控制组件更新的范围对提高应用运行性能尤为重要。我们应该避免状态变量的滥用引起的容器组件的刷新,进而影响帧率。

  • 使用Stack包裹条件渲染组件,减小更新范围

用条件渲染的方式控制组件的显示,在条件发生变化时会引起父组件的重新渲染。如果在同个父组件下存在复杂组件,在高频操作场景会产生性能问题。因此,对于该场景,我们应该用父容器组件包裹可能会频繁条件变化的组件

  • 减少不必要的参数层次传递

@State+@Prop、@State+@Link、@State+@Observed+@ObjectLink三种方案的实现方式是逐级向下传递状态,当共享状态的组件间层级相差较大时,会出现状态层层传递的现象。对于没有使用该状态的中间组件而言,这是“额外的消耗”。因此,对于跨越多层的状态变量传递,使用@Provide+@Consume方案更为合理。

  • 避免滥用@Provide+@Consume

在父子组件关联的场景下,@Provide+@Consume开销要大于@State+@Prop/@Link,因此在该场景下推荐使用@State+@Prop/@Link的组合。

2、精准控制状态变量关联组件数量

应该控制状态变量关联的组件数量,如果一个状态关联过多的组件,当这个变量更新时会引起过多的组件重新绘制渲染,建议关联数量限制在20个以内。

  • 控制状态变量关联组件数量
  • 控制对象级状态变量成员数量

应该控制对象级状态变量的成员变量关联的组件数量。开发者封装一个数据结构类用于进行状态变量关联时,应该避免过多的成员变量关联大量ArkUI组件,这种情况下,当这个大对象的一个成员变量更新时,会导致所有关联这个大对象的组件都同时进行刷新,造成不必要的性能损耗,从而影响帧率。

3、 避免不必要的创建和读取状态变量

避免不必要的创建和读取状态变量,减少性能损耗。

  • 1、删除冗余的状态变量标记

状态变量的管理有一定的开销,应在合理场景使用,普通的变量用状态变量标记可能会导致性能劣化

  • 2、避免在For/while等循环函数中重复读取状态变量

状态变量的读取耗时远大于普通变量的读取耗时,因此要避免重复读取状态变量,而是应该放在循环外面读取,例如在打印For/while循环中打印状态变量的日志信息

二、合理使用系统的高频回调接口,删除不必要的Trace和日志打印,避免冗余操作,减少系统开销

1、避免在系统高频回调用进行冗余和耗时操作

应该避免在onScroll、onAreaChange等系统高频的回调接口中进行冗余和耗时操作,这些接口在系统的每一帧绘制中都会执行回调操作,因此在这些接口中进行冗余和耗时操作会大量消耗系统资源,影响应用运行性能。

  • 避免在系统高频回调用打印Trace

Trace的打印是会额外消耗系统性能的,因此应该避免在这些系统高频回调接口中打印Trace,

  • 避免在系统高频回调用打印日志

日志的打印是会额外消耗系统性能的,特别是有些日志还读取了状态变量的信息,会加剧资源开销,因此应该避免在这些系统高频回调接口中打印日志

2、删除冗余Trace和日志打印

Trace和日志打印会比较消耗系统性能,因此我们应该避免冗余的Trace和日志打印。推荐在Release版本中,尽量删除所有Trace信息,删除Debug日志,减少额外的系统开销。

  • 在Release版本中删除Trace

Trace会比较消耗系统性能,建议在Release版本删除Trace打印。

  • 在Release版本中删除Debug日志

虽然在Release版本中不会打印debug级别日志,但是如果在日志的入参中进行了参数拼接,字符串拼接的逻辑还是会执行,会有冗余开销,因此建议在Release版本删除Debug日志打印

3、避免设置冗余系统回调监听

冗余的系统回调监听,会额外消耗系统开销去做计算和函数回调消耗。比如设置了onAreaChange,就算回调中没有任何逻辑,系统也会在C++侧去计算该组件的大小和位置变化情况,并且把结果回调到TS侧,额外消耗了系统开销。

三、使用性能工具分析和定位问题

学会合理使用工具进行问题分析和定位,提升问题解决效率。

1、学会使用IDE的Profier性能分析工具

通过使用Profier工具,定位应用开发过程中的各种性能问题,详细的使用方法可以参考下列文章:性能分析工具CPU Profiler、页面布局检查器ArkUI Inspector、内存分析器Allocation Profiler、 帧率分析工具 Frame Profiler、 启动分析工具Launch Profiler、内存快照Snapshot Profiler、耗时分析器Time Profiler。

2、 使用SmartPerf-Host分析应用性能

SmartPerf-Host是一款深入挖掘数据、细粒度展示数据的性能功耗调优工具,可采集CPU调度、频点、进程线程时间片、堆内存、帧率等数据,采集的数据通过泳道图清晰地呈现给开发者,同时通过GUI以可视化的方式进行分析。工具当前为开发者提供了五个分析模板,分别是帧率分析、CPU/线程调度分析、应用启动分析、TaskPool分析、动效分析。

3、使用HiDumper命令行工具优化性能

HiDumper是系统为开发、测试人员、IDE工具提供的系统信息获取工具,帮助开发者分析、定位问题。在应用开发过程中,开发者可以使用Hidumper命令行工具获取UI界面组件树信息,配合ArkUI Inspector等图形化工具定位布局性能问题;还可以使用该命令行工具获取如内存和CPU使用情况等各项系统数据,对应用性能进行评估。

4、使用状态变量组件定位工具分析状态变量关联信息

开发者可以使用状态变量组件定位工具获取状态管理相关信息,例如自定义组件拥有的状态变量、状态变量的同步对象和关联组件等,了解状态变量影响UI的范围,写出高性能应用代码。

5、 使用常用trace使用指导协助定位性能问题

HarmonyOS的DFX子系统提供了为应用框架以及系统底座核心模块的性能打点能力,每一处打点即是一个Trace,其上附带了记录执行时间、运行时格式化数据、进程或线程信息等。开发者可以使用SmartPerf-Host调试工具对Trace进行解析,在其绘制的泳道图中,对应用运行过程中的性能热点进行分析,得出优化方案。