相关问题
Span组件禁用控制(enable)、显隐控制(visibility)属性设置无效
1696浏览 • 1回复 待解决
HarmonyOS visibility(Visibility.None) 显隐控制会造成组件的删除重建吗
283浏览 • 1回复 待解决
不使用弹窗,通过 stack 和属性显隐模拟一个弹窗
633浏览 • 1回复 待解决
#鸿蒙学习大百科#如何合理选择状态装饰器?
111浏览 • 0回复 待解决
目前是否支持在组件的链式声明中进行条件渲染
632浏览 • 1回复 待解决
json5文件是否支持编码进行某些条件控制?
158浏览 • 1回复 待解决
HarmonyOS DatePicker是否支持传入参数控制选择格式?
159浏览 • 1回复 待解决
ArkUI节点模型和渲染机制
939浏览 • 1回复 待解决
gamePlayerId和teamPlayerId怎么选择?
1736浏览 • 1回复 待解决
HarmonyOS的音频渲染和视频渲染相关接口文档或者samplecode
234浏览 • 1回复 待解决
WebView进程模型和渲染机制是什么
1999浏览 • 1回复 待解决
显式动画请求绘制帧率
194浏览 • 1回复 待解决
HarmonyOS SDK和openHarmony SDK怎么选择?
7901浏览 • 1回复 待解决
HarmonyOS 关于菜单(Menu)组件,如何控制当条件不满足时点击按钮不显示菜单?
142浏览 • 1回复 待解决
某个查询条件计算太复杂,没法通过sql查出,但是前端有page_size参数和其它条件参数,这种怎么操作
1777浏览 • 2回复 待解决
一多断点怎么设置比较合理
1027浏览 • 1回复 待解决
ets的中文字符的长度和后端不一样是否合理
317浏览 • 1回复 待解决
如何选择PolarDB迁移类型和迁移对象?
2982浏览 • 1回复 待解决
HarmonyOS 绘制组件和画布组件选择问题
274浏览 • 1回复 待解决
关于router和Navigation要选择哪个使用
472浏览 • 2回复 待解决
一个EglSurface支持同时显屏和输出到编码器吗?
213浏览 • 1回复 待解决
PostgreSQL WHERE 计数条件
2822浏览 • 2回复 待解决
HarmonyOS如何控制打开和关闭手电筒
295浏览 • 1回复 待解决
HarmonyOS如何根据条件加载页面
223浏览 • 1回复 待解决
ets的text input手动控制获得和失去焦点
4506浏览 • 1回复 待解决
开发者可以通过条件渲染或显隐控制两种方式来实现组件在显示和隐藏间的切换。本文从两者原理机制的区别出发,对二者适用场景分别进行说明,实现相应适用场景的示例并给出性能对比数据。
条件渲染
if/else条件渲染是ArkUI应用开发框架提供的渲染控制的能力之一。条件渲染可根据应用的不同状态,渲染对应分支下的UI描述。条件渲染的作用机制如下:
关于条件渲染的详细说明,可以参考if/else:条件渲染。
显隐控制
显隐控制visibility是ArkUI应用开发框架提供的组件通用属性之一。开发者可以通过设定组件属性visibility不同的属性值,进而控制组件的显隐状态。visibility属性值及其描述如下:
名称
描述
Visible
组件状态为可见
Hidden
组件状态为不可见,但参与布局、进行占位
None
组件状态为不可见,不参与布局、不进行占位
关于显隐控制的详细说明,可以参考显隐控制。
机制区别
具体针对实现组件显示和隐藏间切换的场景,条件渲染和显隐控制的作用机制区别总结如下:
机制描述
条件渲染
显隐控制
页面初始构建时,若组件隐藏,组件是否会被创建
否
是
若组件由显示变为隐藏时,组件是否会被销毁、从组件树取下
是
否
若组件隐藏时,是否占位
否
可以配置
适用场景
通过条件渲染或显隐控制,实现组件的显示和隐藏间的切换,两者的适用场景分别如下:
条件渲染的适用场景:
显隐控制的适用场景:
显隐控制
针对显示和隐藏间频繁切换的场景,下面示例通过按钮点击,实现1000张图片显示与隐藏,来简单复现该场景,并进行正反例性能数据的对比。
反例
使用条件循环实现显示和隐藏间的切换。
正例
使用显隐控制实现显示和隐藏间的切换。
效果对比
正反例相同的操作步骤:通过点击按钮,将初始状态为显示的循环渲染组件切换为隐藏状态,再次点击按钮,将隐藏状态切换为显示状态。两次切换间的时间间隔长度,需保证页面渲染完成。
此时组件从显示切换到隐藏状态,由于条件渲染会触发一次销毁组件,再从隐藏切换到显示,二次触发创建组件,此时用条件渲染实现切换的方式, 核心函数forEach耗时1s。
基于上例,由于显隐控制会将组件缓存到组件树,从缓存中取状态值修改,再从隐藏切换到显示,继续从缓存中取状态值修改,没有触发创建销毁组件,此时用显隐控制实现切换的方式,核心函数forEach耗时2ms。
可见,如果组件频繁地在显示和隐藏间切换时,使用显隐控制替代条件渲染,避免组件的频繁创建与销毁,可以提高性能。
条件渲染
针对应用冷启动,加载绘制首页时,如果组件初始不需要显示的场景,下面示例通过初始时,隐藏1000个Text组件,来简单复现该场景,并进行正反例性能数据的对比。
反例
对于首页初始时,不需要显示的组件,通过显隐控制进行隐藏。
正例
对于首页初始时,不需要显示的组件,通过条件渲染进行隐藏。
效果对比
正反例相同的操作步骤:通过hdc命令方式,采集应用主线程冷启动的CPU Profiler数据。具体操作,可以参考应用性能分析工具CPU Profiler的使用指导。
当应用加载绘制首页,大量组件初始不需要显示的冷启动场景时,如果组件初始不需要显示,此时使用显隐控制,启动时即使组件为隐藏状态也会创建组件。在UIAbility启动阶段,以下为使用显隐控制的方式,渲染初始页面initialRenderView耗时401.1ms。
基于上例,如果组件初始不需要显示,此时使用条件渲染由于不满足渲染条件,启动时组件不会创建。在UIAbility启动阶段,以下为使用条件渲染的方式,渲染初始页面initialRenderView耗时12.6ms。
可见,如果在应用冷启动阶段,应用加载绘制首页时,如果组件初始不需要显示,使用条件渲染替代显隐控制,可以减少渲染时间,加快启动速度。
条件渲染和容器限制
针对反复切换条件渲染的控制分支,但切换项仅涉及页面中少部分组件的场景,下面示例通过Column父组件下1000个Text组件,与1个受条件渲染控制的Text组件的组合来说明该场景,并对1个受条件渲染控制的Text组件的外面是否加上容器组件做包裹,做两种情况的正反例性能数据的对比。
反例
没有使用容器限制条件渲染组件的刷新范围,导致条件变化会触发创建和销毁该组件,影响该容器内所有组件都会刷新。
正例
使用容器限制条件渲染组件的刷新范围。
效果对比
正反例相同的操作步骤:通过点击按钮,将初始状态为显示的Text组件切换为隐藏状态,再次点击按钮,将隐藏状态切换为显示状态。两次切换间的时间间隔长度,需保证页面渲染完成。
容器内有Text组件被if条件包含,if条件结果变更会触发创建和销毁该组件,此时影响到父组件Column容器的布局,该容器内所有组件都会刷新,包括模块ForEach,因此导致主线程UI刷新耗时过长。
以下为未使用容器限制条件渲染组件的刷新范围的方式,Column组件被标记脏区,ForEach耗时13ms。
基于上例,容器内有Text组件被if条件包含,if条件结果变更会触发创建和销毁该组件,此时对于这种受状态变量控制的组件,在if外套一层Stack容器,只局部刷新if条件包含的组件。因此减少了主线程UI刷新耗时。
以下为使用容器限制条件渲染组件的刷新范围的方式,Column组件没有被标记脏区,没有ForEach耗时。
可见,如果切换项仅涉及部分组件的情况,且反复切换条件渲染的控制分支,使用条件渲染配合容器限制,精准控制组件更新的范围,可以提升应用性能。
条件渲染和组件复用
针对反复切换条件渲染的控制分支,且控制分支中的每种分支内,组件子树结构都比较复杂的场景,当有可以复用的组件情况时,可以用组件复用配合条件渲染的方式提升性能。下面示例通过定义一个自定义复杂子组件MockComplexSubBranch配合条件渲染,来展示两种场景的性能效果对比,并对该组件复用与否做正反例性能数据的对比。
反例
没有使用组件复用实现条件渲染控制分支中的复杂子组件。
其中MockComplexSubBranch是由3个Flex容器组件分别弹性布局200个Text组件构造而成,用以模拟组件复杂的子树结构,代码如下:
正例
使用组件复用实现条件渲染控制分支中的复杂子组件。
其中MockComplexSubBranch实现如下方所示,AlignContentFlex 代码一致,此处不再赘述。
效果对比
正反例相同的操作步骤:通过点击按钮,Text组件会在Flex容器主轴上,由首端对齐转换为尾端对齐,再次点击按钮,由尾端对齐转换为首端对齐。两次切换间的时间间隔长度,需保证页面渲染完成。
此时由于按钮反复切换了条件渲染分支,且每一分支中的MockComplexSubBranch组件子树结构都比较复杂,会造成大量的组件销毁创建过程,以下为不使用组件复用实现条件渲染控制分支中的子组件的方式,应用Index主页面渲染耗时180ms。
基于上例,考虑到将控制分支中的复杂组件子树结构在父组件中进行组件复用,此时从组件树缓存中拿出子组件,避免大量的组件销毁创建过程,以下为使用组件复用实现条件渲染控制分支中的子组件的方式,应用Index主页面渲染耗时14ms。
可见,针对反复切换条件渲染的控制分支的情况,且控制分支中的组件子树结构比较复杂,使用组件复用机制,可以提升应用性能。