一、丢帧问题优化建议
针对一些常见的丢帧问题,下面列举了一些一优化建议
- 尽量减少布局的嵌套层数,合理使用布局,使用相对布局来减少层级
- 使用组件复用减少组件的重复创建与渲染
- 合理管理状态变量,精准控制组件的更新范围,避免冗余刷新
- 使用LazyForEach加载长列表,长列表的优化的优化可以参考长列表加载性能优化
- 使用系统提供的动画接口,减少动画丢帧
总结来说,有几个关键词:
(1)嵌套
(2)组件复用
(3)控制组件更新范围
(4)lazyForEach懒加载(适时加载)
(5)系统动画接口
二、点击响应优化实践
- UI优化
- 按需加载优化
- 并发优化、IPC优化
- 代码逻辑优化
- 视觉感知优化
(一)UI优化
主要有以下几点
(1)减少嵌套层级
(2)减少节点
(3)减少渲染时间
(4)用renderGroup缓存动效
(1)减少嵌套层级
应用开发中的用户界面UI(User Interface)是用户与应用程序交互的关键部分。使用不同类型的布局,能在界面显示上达到预期效果,甚至某些方式能将页面排布得更加美观,但也容易引入不合理的结构问题,如果UI界面中存在过度的布局计算,冗余的元素绘制,将会带来设备资源的大量开销,造成响应性能的衰退。
对比指标 | Column/Row | Stack | Flex | RelativeContanier | Grid/GridItem |
---|---|---|---|---|---|
首帧绘制 | 7.13ms | 7.34ms | 11.71ms | 9.13ms | 12.62ms |
Measure | 2.63ms | 2.70ms | 7.59ms | 3.59ms | 8.68ms |
Layout | 0.74ms | 0.77ms | 0.83ms | 0.77ms | 0.92ms |
所以,使用布局时尽量遵循以下原则:
- 在相同嵌套层级的情况下,如果多种布局方式可以实现相同布局效果,优选低耗时的布局,如使用Column、Row替代Flex实现相同的单行布局;
- 在能够通过其他布局大幅优化节点数的情况下,可以使用高级组件替代,如使用RelativeContainer替代Row、Column实现扁平化布局,此时其收益大于布局组件本身的性能差距;
- 仅在必要的场景下使用高耗时的布局组件,如使用Flex实现折行布局、使用Grid实现二维网格布局等;
优化思路:
1.使用Column、Row替代Flex实现相同的单行布局
(2)减少节点
精简节点数,主要两个方向:
1、移除冗余的节点;
2、使用扁平化布局减少节点数。
精简节点数:
布局的嵌套层次过深会导致在创建节点及进行布局时耗费更多时间。因此开发者在开发时,应避免余的嵌套,并尽量使用扁平化布局来优化嵌套层级。减少总节点,主要有两个方向:1、移除余的节点2、使用扁平化布局减少节点数。
扁平化布局:
扁平化布局是一种让页面结构变浅变宽的方式,通过一些高级组件如RelativeContainer、Grid等容器,可以让元素在平面上展开。这种布局方式能够有效减少由于使用线性布局带来的嵌套深度,将其用于描述布局的容器节点进行优化,达到精简节点数的目的。
(3)减少渲染时间
控制元素的显示与隐藏
控制元素显示与隐藏是一种常见的场景,使用if条件判断、Visibility.None等都能够实现该效果。其中if条件判断控制的是组件的创建、布局阶段,visibility属性控制的是元素在布局阶段是否参与布局渲染。为了优化响应性能,在页面初始化时使用if条件判断来控制显示隐藏,对于内存也有较大提升。
优化思路
在页面初始化时使用if条件代替visability属性来控制显示隐藏,对于内存也有较大提升。
(4)用renderGroup缓存动效
在首次绘制组件时,若组件被标记为启用renderGroup状态,将对组件及子组件进行离屏绘制,将绘制结果合并保存到缓存中。此后当需要重新绘制相同组件时,就会优先使用缓存而不必重新绘制了,从而降低绘制负载,进而加快响应速度。
(二)按需加载
主要有两点:懒加载LazyForEach、动态import
(1)懒加载LazyForEach
在List、Grid以及Swiper等容器中,如果要显示的数据非常多(比如>100条),可以使用LazyForEach替换ForEach,解决一次性加载较大数据耗时长、占用过多资源的问题库,提升页面的响应速度。
(2)动态import
一种模块加载机制,允许应用程序在运行时按照实际需求去加载相关模块。在某些条件满足时(比如用户交互时,或ABTest分支切换时)再加载特定模块,如果不是首帧必须显示的内容模块,使用动态加载的方式(awaitimport),延迟模块的加载时间,加快首帧显示的加载速度
(三)并发优化
使用多线程执行耗时操作
应用中的并发优化就是在响应用户操作期间,尽可能地让主线程只执行UI绘制相关的任务,而将非UI的耗时任务分配给其他线程或者延迟处理。通常可以将耗时操作放在TaskPool或者Worker等后台线程中执行。
(四)代码逻辑优化
代码逻辑的优劣对应用响应素的的影响是比较明显的,特别是新页面中的aboutToAppear、onPageShow等生命周期的回调。
代码逻辑的优化可以通过控制不同组件在生命周期中的渲染次序等方式优化响应速度。
通常要注意:
- 选择合适的数据结构
- 合理使用缓存
- 注意对象new和delete的频率
- 状态变量关联的对象要谨慎使用
- 调整代码顺序,次要逻辑让位于界面渲染
(五)视觉感知优化
使用骨架图、转场动画、共享元素、进度条等方式给用户良好的感知
(六)其他优化思路
(1)ArkWeb的场景性能优化
ArkWeb可用于将H5的页面用在鸿蒙上。
优化思路有:预解析优化、预连接优化、预下载优化、预渲染优化、同层渲染等
三、总结
(一)丢帧问题优化思路
思路:嵌套层数、组件复用、组件更新、适时加载、系统动画
(1)减少嵌套层数
(2)组件复用
(3)控制组件更新范围
(4)lazyForEach懒加载(适时加载)
(5)使用系统动画接口
(二)点击响应优化思路
思路:充分复用、延迟处理、使用并发、代码逻辑、视觉感知
1、充分复用
长列表进行复用、UI import进行复用,使UI效率更高
2、延迟处理,使视域内优先级最高
Task work子线程中进行处理等方式
3、使用并发,充分利用CPU多核性能
4、代码逻辑优化
5、视觉感知优化