このページでは、ビジュアルツリーの要素を管理するために推奨される方法を説明します。
要素のプーリングは、要素を毎回 new() で作成して解放せず、後で再作成する可能性のある要素を保持しておくことです。
プールするすべての要素を完全に制御し、それらをプールに戻す前に正しくリセットすることが重要です。そうしないと、プーリングシステムが不安定になり、問題が発生することがあります。例えば、イベントコールバックの登録中や、内部のシリアル化されていない状態の設定中に要素のプーリングを行うと、同時に要素をクリーンアップすることはできません。
ビジュアル要素の数を少なくするには、可能な限り ListView を使用します。ListView は要素をプールし、ユーザーのスクロールに合わせて要素を再利用します。
または、ListView に似た独自のプールとリサイクルのメカニズムを実装し、以下を使用して可視領域を管理することもできます。
GeometryChangedEvent を使用します。VisualElement.layout プロパティを使用します。
VisualElement.RemoveFromHierarchy() を使用して階層から要素を削除し、その要素への参照を削除すると、その要素はガベージコレクションされます。これにより、CPU と GPU のコストがゼロになり、メモリが大幅に解放されます。ただし、要素を再作成して階層にリロードするには時間とコストがかかります。これを避けるには、階層に要素を事前作成し、USS スタイルのプロパティを使用して非表示にし、必要なときだけ表示します。スタイルを適用すると一般的には処理が高速になりますが、同時に多数の要素を作成するとメモリの使用量が増加する可能性があります。
以下では、要素を非表示にするさまざまな方法と、プロセッサーとメモリ使用量への影響について説明します。
visibility: hidden; で非表示にするこの方法では、子孫は visibility スタイルをオーバーライドできます。
以下の表は、visibility スタイルでビジュアル要素を非表示または表示する場合のシングルフレームコストのさまざまな側面を示しています。
| Aspect | visibility: hidden; |
visibility: visible; |
|---|---|---|
| スタイル | 要素と子孫要素が可視性を伝播するかどうか評価されます。 | 要素と子孫要素が可視性を伝播するかどうか評価されます。 |
| レイアウトデータ | 保持される | なし |
| レンダリングコマンド | 削除され割り当て解除されます。 | 再作成され、コマンドチェーンに再挿入されます。 |
| メッシュ | 割り当て解除のためにスケジュールされます。 | 再テッセレーションされます。 |
以下の表は、visibility スタイルでビジュアル要素を非表示にしたときの CPU と GPU のフレームごとの動作を示しています。
| プロセッサー | Aspect| フレームごとの動作 | | — | — | — | | CPU | スタイル | 要素とその子孫に対して完全に評価されます。 | | |レイアウトデータ | Updated| | |テッセレーション | ステンシルマスキングメッシュのみが含まれる最小限の影響 (該当する場合)。 | | |レンダリングコマンド | 通常の可視ジオメトリを描画するコマンドはありません。ただし、ステンシルマスキングメッシュは、ステンシルからプッシュまたはポップするようにレンダリングされ、表示される可能性のある子孫がマスクされるようにします。 | | GPU |メッシュ | ステンシルマスキングメッシュの頂点およびフラグメントシェーディング。|
opacity: 0; で非表示にするこの方法では、フラグメントシェーダーがすべての要素を処理するため、コンテンツがビューポートにある場合、GPU の使用率が高くなり、オーバードローが大量に発生する可能性があります。
以下の表は、opacity スタイルでビジュアル要素を非表示または表示する場合のシングルフレームコストを示しています。
| アクション | シングルフレームコスト |
|---|---|
opacity: 0; |
opacity を初めて 1 以外の値に設定すると、UI Toolkit レンダラーは頂点を修正し、GPU での不透明度の適用を加速させます。これにより、1 回だけの最小限の CPU コストが発生します。通常は無視できる程度ですが、要素に多数の子孫がある場合や、修正する頂点が多い場合は、このコストは顕著になる可能性があります。このコストは、ビジュアルツリーから要素を削除され、再度追加されない限り、再び発生することはありません。 |
opacity: 1; |
なし |
以下の表は、opacity スタイルでビジュアル要素を非表示にしたときの CPU と GPU のフレームごとの動作を示しています。
| プロセッサー | Aspect| フレームごとの動作 |
| — | — | — |
| CPU |スタイル | 要素とその子孫に対して完全に評価されます。 |
|
|テッセレーション | 通常どおりに動作し、変更に対応します。 |
|
|レンダリングコマンド | 実行される |
| GPU | メッシュ | 頂点シェーダーは、visibility が 1 に設定されているかのように動作します。同様に、フラグメントシェーダーも visibility が 1 であるかのように動作します。これは、GPU 依存のプロジェクトではオーバードローにつながる可能性があるため、問題になる場合があります。 |
display: none; で非表示にするこの方法では、要素がレイアウトツリーから削除されたかのように動作し、他の要素のレイアウトに影響を与える可能性があります。
以下の表は、display スタイルでビジュアル要素を非表示または表示する場合のシングルフレームコストのさまざまな側面を示しています。
| Aspect | display: none; |
display: flex; |
|---|---|---|
| レイアウトデータ | 他の要素のレイアウトを再計算する可能性があります。 | 保留中のレイアウト変更が処理されます。 |
| レンダリングコマンド/メッシュ | レイアウト変更によって影響を受ける要素が再作成されます。 |
|
以下の表は、display スタイルでビジュアル要素を非表示にしたときの CPU のフレームごとの動作を示しています。GPU コストは発生しないことに注意してください。
| Aspect | フレームごとの動作 |
|---|---|
| レイアウトデータ | 保持されますが無効になる可能性があり、更新されていません。 |
| レンダリングコマンド | 保持されますが、実行中にスキップされる可能性があります。スキップする方法は非常に安価ですが、完全に無料ではありません。コストはコマンド数に比例します。 |
| メッシュ | 保持されますが無効になる可能性があり、更新されていません。 |
translate: -5000px -5000px; を DynamicTransform 使用のヒントと組み合わせて使用すると、要素をビューポートの外へ移動できます。ジオメトリは完全にアクティブなままになるため、画面上に要素を再表示するときに使用する CPU は最小限に抑えられます。ただし、GPU は頂点の処理を継続します。これは、シナリオによっては許容できる場合があります。
変換が計算され、GPU メモリにアップロードされます。これは一般的に高速です。
以下の表は、ビジュアル要素をビューポートの外で変換して非表示にした場合の、CPU と GPU のフレームごとの動作を示しています。
| プロセッサー | Aspect| フレームごとの動作 | | — | — | — | | CPU|スタイル | Updated | | |レイアウト日付 | Updated | | |ドローコール | 実行される | | GPU |メッシュ | 頂点は影になる |
VisualElement.RemoveFromHierarchy() メソッドを使用して階層から要素を削除すると、CPU と GPU のメモリが解放され、計算コストが低減します。
以下の表は、ビジュアル要素を階層から削除して非表示または表示する場合のシングルフレームコストを示しています。
| Aspect | Remove (削除) | 加える |
|---|---|---|
| スタイル | なし | サブツリーに対して更新されます。 |
| Layout | なし | サブツリーと他の要素に対して再計算されます。 |
| レンダリングコマンド/メッシュ | レイアウト変更によって影響を受ける要素が再作成されます。 |
|
以下の表は、さまざまな方法で要素を非表示にした後のメモリ使用量をまとめたものです。
| プロセッサー |Aspect| visibility:hidden; | opacity:0; | display:None; | ビューポートの外での変換 | 階層からの削除 |
| — | — | — | — | — | — | — |
| CPU |スタイル |保持される | 保持される | 保持される | 保持される | 解放される |
|
|Layout | 保持される | 保持される | 保持される | 保持される | 保持される [1] |
|
|レンダリングコマンド/メッシュ | 解放される | 保持される | 保持される | 保持される | 解放される |
| GPU |メッシュ | 解放される | 保持される | 保持される | 保持される | 解放される |
レイアウトメモリは、要素用に予約されているため保持されます。VisualElement がガベージコレクションされると、レイアウトメモリはプールに返され、他の要素で使用できるようになります。 ↩