引
@ComponentV2 装饰器是可以接收参数的,叫freezeWhenInactive, 顾名思义,就是当组件变成Inactive的时候,冻结。其默认值是false。所以如果您没有传参数时,默认不冻结。
冻结到底是一种什么状态呢?说简单点就是状态变量不响应更新。@Monitor修饰的那些状态变量更新检测逻辑也自然不会被回调。
那么为什么要给组件加一种冻结状态呢?
组件冻结功能存在的意义
最重点的原因就是性能优化。想象一种非常复杂的场景,里面有很复杂的界面,当一个状态变量绑定了很多的组价时,当状态变量发生变化,就很可能触发大量的UI刷新。造成界面卡顿。比如:
- 导航组件中的页面发生跳转之后,即使之前的页面已经是不可见的状态了,但是被隐藏的界面中的状态变量发生了更新,却依然会触发UI刷新。我们晓得,通常数据是从服务端请求下来的,什么时候数据到位我们也不是绝对可控的。此时界面已经被用户操作到什么界面了,我们也并非完全可控。有时候数据来了,界面却不需要了。这个很多时候会发生的,也是我工作经验中总结的比较容易出bug的地方,(在Andorid中的基类,或者Fragment基类中,通常研发会补写一种当前页面状态查询方法,大抵原因就是为了应付这种数据页面不对称的问题,但是仍需要子类写一些具体的判断场景,比较麻烦)。这里无论是从性能上,还是从代码的健壮性上,其实都需要拦一道的。freezeWhenInactive,恰恰能够使得@ComponentV2具备"拦一道"的能力。
- 长列表在滚动时,不可见的列表项目仍然持续响应数据的变化,从而消耗了计算资源。
freezeWhenInactive 中的“Inactive”指的是?
这里我稍微扣一下字眼,毕竟源码开发人员,不可能乱起属性名的。当组件处于Inactive的时候就冻结。 那么?Inactive状态具体指的组件是什么状态呢?结果是,不同的组件有各自的inactive标准时刻。看来没白扣。
- 在页面路由代码场景中,非栈顶的界面,是inactive状态
- 在Navigation导航组件的使用场景中,未显示的NavDestination组件,是inactive状态。
- 在TabContent组件中,非当前Tab中的组件,是inactive状态。
冻结行为表征
- 一旦组件发生了冻结,则其内部包含的所有状态变量更新,都不会触发UI的刷新。@Monitor监视器也不会执行。
- 但是当界面恢复了active状态的时候,ArkUI框架便会自动补发之前最后的更新值,从而确保UI的正确性。
自定义组件冻结的使用及表现特征
自定义组件冻结能力的使用通常用在以下三大场景
- 页面路由场景
- Tab页, TabC