Version: 6000.3
语言: 中文
自定义控件库编译疑难解答
使用逻辑封装 UXML 文档

管理元素的最佳实践

本页介绍在可视化树轻量级节点组成的对象图,用于保存窗口或面板中的所有元素。它定义了使用 UI 工具包构建的每个 UI。
请参阅术语表
.

池重复元素

元素池是保留您以后可能重新创建的元素,而不是使用new()每次都放开他们。

重要的是要完全控制您池中的所有元素,并确保在将它们返回池之前正确重置它们。否则,池化系统可能会变得不稳定和麻烦。例如,如果在注册事件回调或同时设置内部非序列化状态时池化元素,则无法清理元素。

保持较少的可见元素数量

要保持视觉元素实例化或派生自 C# 的可视化树的节点VisualElement类。您可以设置外观样式、定义行为并将其作为 UI 的一部分显示在屏幕上。更多信息
请参阅术语表
low,请尽可能使用 ListViewListView 在用户滚动时汇集元素并回收元素。

或者,您可以实现类似于 ListView 的自己的池和回收机制,并使用以下内容来管理可见区域:

隐藏元素的不同方法

当您使用VisualElement.RemoveFromHierarchy()若要从层次结构中删除元素并消除对它的引用,将对元素进行垃圾回收。这将 CPU 和 GPU 成本降低到零,并释放大量内存。但是,重新创建元素并在层次结构中重新加载它们是一项缓慢且成本高昂的作。为避免这种情况,您可以在层次结构中预先创建元素,使用 USS 样式属性隐藏它们,并仅在必要时显示它们。虽然应用样式通常更快,但如果同时创建大量元素,可能会导致内存使用量增加。

下面介绍隐藏元素的不同方法以及对处理器和内存使用的影响。

以 USS 样式隐藏visibility: hidden;

通过这种方法,后代可以覆盖visibility风格。

单帧成本

下表描述了使用visibility风格:

方面 visibility: hidden; visibility: visible;
风格 评估元素和后代以传播可见性。 对它和后代进行评估,以传播可见性。
布局数据 保存 没有
渲染命令 已删除并解除分配 重新创建并重新插入到命令链中。
网 格 计划解除分配。 重新细分

每帧行为

下表描述了使用visibility风格:

处理器 方面 每帧行为
中央处理器 风格 对元素及其后代进行全面评估。
布局数据 更新
棋盘形布置 仅涉及的最小影响模板遮罩网格溢出隐藏有圆角或矢量图像背景。
请参阅术语表
,如果适用。
渲染命令 没有用于绘制常规可见几何图形的命令。但是,模板遮罩网格仍会呈现为从模板中推送或弹出,从而确保潜在的可见后代被屏蔽。
图形处理器 网 格 模板遮罩网格上的顶点和片段着色。

以 USS 样式隐藏opacity: 0;

使用此方法,如果内容位于视口用户在屏幕上应用的可见区域。
请参阅术语表
,作为片段着色器在 GPU 上运行的程序。更多信息
请参阅术语表
处理所有元素,可能导致严重透支。

单帧成本

下表描述了使用opacity风格:

行动 单帧成本
opacity: 0; 第一次将opacity设置为1,UI 工具包渲染器会修改顶点以加速在 GPU 上应用不透明度。这会触发一次性的最低 CPU 成本。虽然通常可以忽略不计,但如果元素具有大量后代或有许多顶点需要修改,则此成本可能会变得明显。除非从可视化树中删除元素并重新添加,否则不会再次产生此成本。
opacity: 1; 没有

每帧行为

下表描述了使用opacity风格:

处理器 方面 每帧行为
中央处理器 风格 对元素及其后代进行全面评估。
棋盘形布置 正常运行并响应变化。
渲染命令 执行
图形处理器 网 格 顶点着色器 渲染模型时在 3D 模型的每个顶点上运行的程序。更多信息
请参阅术语表
作方式就好像visibility设置为1.同样,片段着色器的功能也类似于visibility1.这在 GPU 绑定的项目中可能是有害的,因为它可能导致过度绘制。

以 USS 样式隐藏display: none;

使用这种方法,元素的行为就像从布局树中删除一样,这可能会影响其他元素的布局。

单帧成本

下表描述了使用display风格:

方面 display: none; display: flex;
布局数据 可能会重新计算其他元素的布局。 将处理待处理的布局更改。
渲染命令/网格体 为受布局更改影响的元素重新生成。
  • 为受布局更改影响的元素重新生成。
  • 处理挂起的更改。

每帧行为

下表描述了使用display风格。请注意,没有 GPU 成本。

方面 每帧行为
布局数据 保留,但可能会失效且未更新。
渲染命令 尽管保留,但在执行过程中可以跳过它们。跳过它们的方式非常便宜,但并非完全免费。成本与命令数量成正比。
网 格 保留,但可能会失效且未更新。

在视口之外进行转换

您可以使用translate: -5000px -5000px;结合DynamicTransform将元素移出视口的用法提示。几何体保持完全活动状态,从而在屏幕上恢复元素时将 CPU 使用率降至最低。但是,GPU 会继续处理顶点,这可能是可以接受的,具体取决于方案。

单帧成本

转换被计算并上传到 GPU 内存中,这通常很快。

每帧行为

下表描述了通过在视口外部转换视觉元素来隐藏视觉元素时CPU和GPU的每帧行为:

处理器 方面 每帧行为
中央处理器 风格 更新
布局日期 更新
绘制调用 执行
图形处理器 网 格 顶点是阴影。

从层次结构中删除

当您使用VisualElement.RemoveFromHierarchy()方法从层次结构中删除元素,您可以释放 CPU 和 GPU 内存,从而消除任何计算成本。

单帧成本

下表描述了通过从层次结构中删除视觉元素来隐藏或显示可视元素时的单帧成本:

方面 删除
风格 没有 更新了子树。
布局 没有 为子树和可能的其他元素重新计算。
渲染命令/网格 为受布局更改影响的元素重新生成。
  • 为受布局更改影响的元素重新生成。
  • 处理挂起的更改。

隐藏后的内存使用情况

下表总结了使用不同方法隐藏元素后的内存使用情况:

处理器 方面 visibility:hidden; opacity:0; display:None; 从视口转换出来 从层次结构中删除
中央处理器 风格 保留 保留 保留 保留 释放
布局 保留 保留 保留 保留 保留[1]
渲染命令/网格 释放 保留 保留 保留 释放
图形处理器 网 格 释放 保留 保留 保留 释放

  1. 布局内存被保留,因为它仍然为元素保留。垃圾回收 VisualElement 时,布局内存将返回到池,使其可供其他元素使用。

自定义控件库编译疑难解答
使用逻辑封装 UXML 文档