1e41f4b71Sopenharmony_ci# Properly Choosing Between if/else and Visibility
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ciBoth conditional rendering and the visibility attribute to switch components between visibility states. This document is intended to help you choose between these two approaches, by comparing their mechanism, usage scenarios, and performance in typical examples.
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ci## Mechanism
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ci### Conditional Rendering
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ciYou can use the **if/else** statement for conditional rendering, one of the rendering control capabilities provided by the ArkUI application development framework. With conditional rendering, the UI description of a specific branch is rendered based on the application state. The mechanism of condition rendering is as follows:
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci- During initial page construction, conditional statements are evaluated, components in the positive branch are built. If a positive branch is missing, no component is built.
12e41f4b71Sopenharmony_ci- When the application state changes, the conditional statements are re-evaluated. Components in the negative branch are deleted, and those in the positive branch are built. If a positive branch is missing, no component is built.
13e41f4b71Sopenharmony_ci
14e41f4b71Sopenharmony_ciFor details about conditional rendering, see [if/else: Conditional Rendering](../quick-start/arkts-rendering-control-ifelse.md).
15e41f4b71Sopenharmony_ci
16e41f4b71Sopenharmony_ci### Visibility
17e41f4b71Sopenharmony_ci
18e41f4b71Sopenharmony_ciVisibility is one of the universal component attributes provided by ArkUI. You can set the visibility attribute of a component to show or hide the component. The table below describes the visibility attribute values.
19e41f4b71Sopenharmony_ci
20e41f4b71Sopenharmony_ci| Name   | Description                                    |
21e41f4b71Sopenharmony_ci| ------- | ---------------------------------------- |
22e41f4b71Sopenharmony_ci| Visible | The component is visible.                          |
23e41f4b71Sopenharmony_ci| Hidden  | The component is invisible, but still takes up space in the layout.  |
24e41f4b71Sopenharmony_ci| None    | The component is invisible, and does not take up space in the layout.|
25e41f4b71Sopenharmony_ci
26e41f4b71Sopenharmony_ciFor details about the visibility attribute, see [Visibility](../reference/arkui-ts/ts-universal-attributes-visibility.md).
27e41f4b71Sopenharmony_ci
28e41f4b71Sopenharmony_ci### Mechanism Differences
29e41f4b71Sopenharmony_ci
30e41f4b71Sopenharmony_ciThe table below compares the conditional rendering and visibility mechanisms.
31e41f4b71Sopenharmony_ci
32e41f4b71Sopenharmony_ci| Mechanism                                              | Conditional Rendering| Visibility|
33e41f4b71Sopenharmony_ci| ------------------------------------------------------ | -------- | -------- |
34e41f4b71Sopenharmony_ci| Will a component be created if it is invisible during initial page construction?          | No      | Yes      |
35e41f4b71Sopenharmony_ci| Will a component be destroyed and removed from the component tree if it changes from visible to invisible?| Yes      | No      |
36e41f4b71Sopenharmony_ci| Does a component takes up space in the layout when it is invisible?                                | No      | Configurable|
37e41f4b71Sopenharmony_ci
38e41f4b71Sopenharmony_ci## Usage Scenarios
39e41f4b71Sopenharmony_ci
40e41f4b71Sopenharmony_ciConditional rendering and the visibility attribute are applicable in different scenarios.
41e41f4b71Sopenharmony_ci
42e41f4b71Sopenharmony_ciConditional rendering applies to the following scenarios:
43e41f4b71Sopenharmony_ci
44e41f4b71Sopenharmony_ci- To reduce render time and speed up application startup, consider conditional rendering in the cold start phase for components that do not need to be displayed initially when the application loads and draws the home page.
45e41f4b71Sopenharmony_ci- If a component does not frequently switch between visibility states, or does not need to be displayed most of the time, you are advised to use conditional rendering, so as to reduce GUI complexity, reduce nesting, and improve performance.
46e41f4b71Sopenharmony_ci- If memory is a critical concern, prefer conditional rendering for memory-hogging components, so they can be destroyed in time when they are not needed.
47e41f4b71Sopenharmony_ci- If the component subtree structure is complex and the conditions for rendering change frequently, it is recommended that you use conditional rendering with the component reuse mechanism to improve application performance.
48e41f4b71Sopenharmony_ci- If only some components need to be switched between visibility states and the conditions for rendering change frequently, combine conditional rendering with container restrictions to precisely control the component render scope to improve application performance.
49e41f4b71Sopenharmony_ci
50e41f4b71Sopenharmony_ciThe visibility attribute applies to the following scenarios:
51e41f4b71Sopenharmony_ci
52e41f4b71Sopenharmony_ci- If a component is frequently switched between visibility states, the visibility attribute is a better choice, because it avoids frequent creation and destruction of the component and thereby improves performance.
53e41f4b71Sopenharmony_ci- If a component needs to take up space in the page layout when invisible, use the visibility attribute.
54e41f4b71Sopenharmony_ci
55e41f4b71Sopenharmony_ci### When Visibility Is Preferred
56e41f4b71Sopenharmony_ci
57e41f4b71Sopenharmony_ciThe following exemplifies why the visibility attribute is a better choice for components that are frequently switched between visibility states. In the examples below, a button is used to show and hide 1000 images.
58e41f4b71Sopenharmony_ci
59e41f4b71Sopenharmony_ci**Nonexample**
60e41f4b71Sopenharmony_ci
61e41f4b71Sopenharmony_ciUse conditional statements to switch components between visibility states.
62e41f4b71Sopenharmony_ci
63e41f4b71Sopenharmony_ci```ts
64e41f4b71Sopenharmony_ci@Entry
65e41f4b71Sopenharmony_ci@Component
66e41f4b71Sopenharmony_cistruct WorseUseIf {
67e41f4b71Sopenharmony_ci  @State isVisible: boolean = true;
68e41f4b71Sopenharmony_ci  private data: number[] = [];
69e41f4b71Sopenharmony_ci
70e41f4b71Sopenharmony_ci  aboutToAppear() {
71e41f4b71Sopenharmony_ci    for (let i: number = 0; i < 1000; i++) {
72e41f4b71Sopenharmony_ci      this.data.push(i);
73e41f4b71Sopenharmony_ci    }
74e41f4b71Sopenharmony_ci  }
75e41f4b71Sopenharmony_ci
76e41f4b71Sopenharmony_ci  build() {
77e41f4b71Sopenharmony_ci    Column() {
78e41f4b71Sopenharmony_ci      Button("Switch visible and hidden").onClick(() => {
79e41f4b71Sopenharmony_ci        this.isVisible = !(this.isVisible);
80e41f4b71Sopenharmony_ci      }).width('100%')
81e41f4b71Sopenharmony_ci      Stack() {
82e41f4b71Sopenharmony_ci        if (this.isVisible) {// When conditional rendering is used, components are frequently created and destroyed.
83e41f4b71Sopenharmony_ci          Scroll() {
84e41f4b71Sopenharmony_ci            Column() {
85e41f4b71Sopenharmony_ci              ForEach(this.data, (item: number) => {
86e41f4b71Sopenharmony_ci                Image($r('app.media.icon')).width('25%').height('12.5%')
87e41f4b71Sopenharmony_ci              }, (item: number) => item.toString())
88e41f4b71Sopenharmony_ci            }
89e41f4b71Sopenharmony_ci          }
90e41f4b71Sopenharmony_ci        }
91e41f4b71Sopenharmony_ci      }
92e41f4b71Sopenharmony_ci    }
93e41f4b71Sopenharmony_ci  }
94e41f4b71Sopenharmony_ci}
95e41f4b71Sopenharmony_ci```
96e41f4b71Sopenharmony_ci
97e41f4b71Sopenharmony_ci**Example**
98e41f4b71Sopenharmony_ci
99e41f4b71Sopenharmony_ciUse the visibility attribute to switch components between visibility states.
100e41f4b71Sopenharmony_ci
101e41f4b71Sopenharmony_ci```ts
102e41f4b71Sopenharmony_ci@Entry
103e41f4b71Sopenharmony_ci@Component
104e41f4b71Sopenharmony_cistruct BetterUseVisibility {
105e41f4b71Sopenharmony_ci  @State isVisible: boolean = true;
106e41f4b71Sopenharmony_ci  private data: number[] = [];
107e41f4b71Sopenharmony_ci
108e41f4b71Sopenharmony_ci  aboutToAppear() {
109e41f4b71Sopenharmony_ci    for (let i: number = 0; i < 1000; i++) {
110e41f4b71Sopenharmony_ci      this.data.push(i);
111e41f4b71Sopenharmony_ci    }
112e41f4b71Sopenharmony_ci  }
113e41f4b71Sopenharmony_ci
114e41f4b71Sopenharmony_ci  build() {
115e41f4b71Sopenharmony_ci    Column() {
116e41f4b71Sopenharmony_ci      Button("Switch visible and hidden").onClick(() => {
117e41f4b71Sopenharmony_ci        this.isVisible = !(this.isVisible);
118e41f4b71Sopenharmony_ci      }).width('100%')
119e41f4b71Sopenharmony_ci      Stack() {
120e41f4b71Sopenharmony_ci        Scroll() {
121e41f4b71Sopenharmony_ci          Column() {
122e41f4b71Sopenharmony_ci            ForEach(this.data, (item: number) => {
123e41f4b71Sopenharmony_ci              Image($r('app.media.icon')).width('25%').height('12.5%')
124e41f4b71Sopenharmony_ci            }, (item: number) => item.toString())
125e41f4b71Sopenharmony_ci          }
126e41f4b71Sopenharmony_ci        }.visibility(this.isVisible ? Visibility.Visible : Visibility.None)// When the visibility attribute is used, components are not frequently created and destroyed.
127e41f4b71Sopenharmony_ci      }
128e41f4b71Sopenharmony_ci    }
129e41f4b71Sopenharmony_ci  }
130e41f4b71Sopenharmony_ci}
131e41f4b71Sopenharmony_ci```
132e41f4b71Sopenharmony_ci
133e41f4b71Sopenharmony_ci**Effect Comparison**
134e41f4b71Sopenharmony_ci
135e41f4b71Sopenharmony_ciPerform the same steps for the preceding example and nonexample: Click the button to hide the initially visible components, and then click the button again to show the components. Make sure the interval between showing and hiding the components is long enough for the page rendering to be complete.
136e41f4b71Sopenharmony_ci
137e41f4b71Sopenharmony_ciIn the case of conditional rendering, components are destroyed when hidden, and re-created when shown. In this case, the core function **forEach** takes 1s, as shown below.
138e41f4b71Sopenharmony_ci
139e41f4b71Sopenharmony_ci![img](./figures/WorseUseIf.png) 
140e41f4b71Sopenharmony_ci
141e41f4b71Sopenharmony_ciThe visibility attribute does not involve creation and destruction of components. Instead, it caches the components to the component tree, obtains the state value from the cache, and changes the value to switch the components between visibility states. In this case, the core function **forEach** takes 2 ms, as shown below.
142e41f4b71Sopenharmony_ci
143e41f4b71Sopenharmony_ci![img](./figures/BetterUseVisibility.png) 
144e41f4b71Sopenharmony_ci
145e41f4b71Sopenharmony_ciBy comparing the performance data, we can learn that, regarding components that are frequently switched between visibility states, the visibility attribute outperforms conditional rendering, because it avoids frequent component creation and destruction.
146e41f4b71Sopenharmony_ci
147e41f4b71Sopenharmony_ci### When Conditional Rendering Is Preferred
148e41f4b71Sopenharmony_ci
149e41f4b71Sopenharmony_ciConditional rendering applies in the cold start phase for components that do not need to be displayed initially when the application loads and draws the home page. In the examples below, there are invisible 1000 **\<Text>** components at initial render.
150e41f4b71Sopenharmony_ci
151e41f4b71Sopenharmony_ci**Nonexample**
152e41f4b71Sopenharmony_ci
153e41f4b71Sopenharmony_ciUse the visibility attribute to hide components that do not need to be displayed at initial render of the home page.
154e41f4b71Sopenharmony_ci
155e41f4b71Sopenharmony_ci```ts
156e41f4b71Sopenharmony_ci@Entry
157e41f4b71Sopenharmony_ci@Component
158e41f4b71Sopenharmony_cistruct WorseUseVisibility {
159e41f4b71Sopenharmony_ci  @State isVisible: boolean = false; // The component is invisible during application startup.
160e41f4b71Sopenharmony_ci  private data: number[] = [];
161e41f4b71Sopenharmony_ci
162e41f4b71Sopenharmony_ci  aboutToAppear() {
163e41f4b71Sopenharmony_ci    for (let i: number = 0; i < 1000; i++) {
164e41f4b71Sopenharmony_ci      this.data.push(i);
165e41f4b71Sopenharmony_ci    }
166e41f4b71Sopenharmony_ci  }
167e41f4b71Sopenharmony_ci
168e41f4b71Sopenharmony_ci  build() {
169e41f4b71Sopenharmony_ci    Column() {
170e41f4b71Sopenharmony_ci      Button("Show the Hidden on start").onClick(() => {
171e41f4b71Sopenharmony_ci        this.isVisible = !(this.isVisible);
172e41f4b71Sopenharmony_ci      }).width('100%')
173e41f4b71Sopenharmony_ci      Stack() {
174e41f4b71Sopenharmony_ci        Image($r('app.media.icon')).objectFit(ImageFit.Contain).width('50%').height('50%')
175e41f4b71Sopenharmony_ci        Scroll() {
176e41f4b71Sopenharmony_ci          Column() {
177e41f4b71Sopenharmony_ci            ForEach(this.data, (item: number) => {
178e41f4b71Sopenharmony_ci              Text(`Item value: ${item}`).fontSize(20).width('100%').textAlign(TextAlign.Center)
179e41f4b71Sopenharmony_ci            }, (item: number) => item.toString())
180e41f4b71Sopenharmony_ci          }
181e41f4b71Sopenharmony_ci        }.visibility(this.isVisible ? Visibility.Visible : Visibility.None)// When the visibility attribute is used, the component is created at application startup even when it is invisible.
182e41f4b71Sopenharmony_ci      }
183e41f4b71Sopenharmony_ci    }
184e41f4b71Sopenharmony_ci  }
185e41f4b71Sopenharmony_ci}
186e41f4b71Sopenharmony_ci```
187e41f4b71Sopenharmony_ci
188e41f4b71Sopenharmony_ci**Example**
189e41f4b71Sopenharmony_ci
190e41f4b71Sopenharmony_ciUse conditional rendering to hide components that do not need to be displayed at initial render of the home page.
191e41f4b71Sopenharmony_ci
192e41f4b71Sopenharmony_ci```ts
193e41f4b71Sopenharmony_ci@Entry
194e41f4b71Sopenharmony_ci@Component
195e41f4b71Sopenharmony_cistruct BetterUseIf {
196e41f4b71Sopenharmony_ci  @State isVisible: boolean = false; // The component is invisible during application startup.
197e41f4b71Sopenharmony_ci  private data: number[] = [];
198e41f4b71Sopenharmony_ci
199e41f4b71Sopenharmony_ci  aboutToAppear() {
200e41f4b71Sopenharmony_ci    for (let i: number = 0; i < 1000; i++) {
201e41f4b71Sopenharmony_ci      this.data.push(i);
202e41f4b71Sopenharmony_ci    }
203e41f4b71Sopenharmony_ci  }
204e41f4b71Sopenharmony_ci
205e41f4b71Sopenharmony_ci  build() {
206e41f4b71Sopenharmony_ci    Column() {
207e41f4b71Sopenharmony_ci      Button("Show the Hidden on start").onClick(() => {
208e41f4b71Sopenharmony_ci        this.isVisible = !(this.isVisible);
209e41f4b71Sopenharmony_ci      }).width('100%')
210e41f4b71Sopenharmony_ci      Stack() {
211e41f4b71Sopenharmony_ci        Image($r('app.media.icon')).objectFit(ImageFit.Contain).width('50%').height('50%')
212e41f4b71Sopenharmony_ci        if (this.isVisible) { // When conditional rendering is used, the component is created at application startup when it is invisible.
213e41f4b71Sopenharmony_ci          Scroll() {
214e41f4b71Sopenharmony_ci            Column() {
215e41f4b71Sopenharmony_ci              ForEach(this.data, (item: number) => {
216e41f4b71Sopenharmony_ci                Text(`Item value: ${item}`).fontSize(20).width('100%').textAlign(TextAlign.Center)
217e41f4b71Sopenharmony_ci              }, (item: number) => item.toString())
218e41f4b71Sopenharmony_ci            }
219e41f4b71Sopenharmony_ci          }
220e41f4b71Sopenharmony_ci        }
221e41f4b71Sopenharmony_ci      }
222e41f4b71Sopenharmony_ci    }
223e41f4b71Sopenharmony_ci  }
224e41f4b71Sopenharmony_ci}
225e41f4b71Sopenharmony_ci```
226e41f4b71Sopenharmony_ci
227e41f4b71Sopenharmony_ci**Effect Comparison**
228e41f4b71Sopenharmony_ci
229e41f4b71Sopenharmony_ciPerform the same steps for the preceding example and nonexample: Run hdc commands to collect the CPU Profiler data of the main thread during the cold start of the application. For details, see [CPU Profiler](./application-performance-analysis.md#collecting-data-using-hdc-shell-commands).
230e41f4b71Sopenharmony_ci
231e41f4b71Sopenharmony_ciWhen the application loads and draws the home page during the cold start, using the visibility attribute creates the components that do not need to be displayed initially, which increases the render time. As shown below, in the UIAbility startup phase, it takes 401.1 ms to render the initial view with the visibility attribute.
232e41f4b71Sopenharmony_ci
233e41f4b71Sopenharmony_ci![img](./figures/WorseUseVisibility.png) 
234e41f4b71Sopenharmony_ci
235e41f4b71Sopenharmony_ciTo reduce the render time during the cold start, use conditional rendering. In this case, components that do not need to be displayed initially will not be created. As shown below, in the UIAbility startup phase, it takes 12.6 ms to render the initial view with conditional rendering.
236e41f4b71Sopenharmony_ci
237e41f4b71Sopenharmony_ci![img](./figures/BetterUseIf.png) 
238e41f4b71Sopenharmony_ci
239e41f4b71Sopenharmony_ciBy comparing the performance data, we can learn that, regarding components that do not need to be displayed during the application cold start, conditional rendering can reduce the render time and speed up application startup.
240e41f4b71Sopenharmony_ci
241e41f4b71Sopenharmony_ci### Conditional Rendering and Container Restrictions
242e41f4b71Sopenharmony_ci
243e41f4b71Sopenharmony_ciIf only some components need to be switched between visibility states and the conditions for rendering change frequently, you can combine conditional rendering with container restrictions to precisely control the component render scope. The following exemplifies the effect of container restrictions in this usage scenario: A **\<Column>** component is used to hold 1000 **\<Text>** components, and one of the **\<Text>** components is controlled with conditional rendering.
244e41f4b71Sopenharmony_ci
245e41f4b71Sopenharmony_ci**Nonexample**
246e41f4b71Sopenharmony_ci
247e41f4b71Sopenharmony_ciWhen conditional rendering is used without container restrictions, the container is created and destroyed upon condition changes, which causes all components in the container to be re-rendered.
248e41f4b71Sopenharmony_ci
249e41f4b71Sopenharmony_ci```ts
250e41f4b71Sopenharmony_ci@Entry
251e41f4b71Sopenharmony_ci@Component
252e41f4b71Sopenharmony_cistruct RenderControlWithoutStack {
253e41f4b71Sopenharmony_ci  @State isVisible: boolean = true;
254e41f4b71Sopenharmony_ci  private data: number[] = [];
255e41f4b71Sopenharmony_ci
256e41f4b71Sopenharmony_ci  aboutToAppear() {
257e41f4b71Sopenharmony_ci    for (let i: number = 0; i < 1000; i++) {
258e41f4b71Sopenharmony_ci      this.data.push(i);
259e41f4b71Sopenharmony_ci    }
260e41f4b71Sopenharmony_ci  }
261e41f4b71Sopenharmony_ci
262e41f4b71Sopenharmony_ci  build() {
263e41f4b71Sopenharmony_ci    Column() {
264e41f4b71Sopenharmony_ci      Stack() {
265e41f4b71Sopenharmony_ci        Scroll() {
266e41f4b71Sopenharmony_ci          Column() {// The re-render scope is extended to this layer.
267e41f4b71Sopenharmony_ci            if (this.isVisible) {// The container is created and destroyed upon condition changes, which causes all components in the container to be re-rendered.
268e41f4b71Sopenharmony_ci              Text('New item').fontSize(20)
269e41f4b71Sopenharmony_ci            }
270e41f4b71Sopenharmony_ci            ForEach(this.data, (item: number) => {
271e41f4b71Sopenharmony_ci              Text(`Item value: ${item}`).fontSize(20).width('100%').textAlign(TextAlign.Center)
272e41f4b71Sopenharmony_ci            }, (item: number) => item.toString())
273e41f4b71Sopenharmony_ci          }
274e41f4b71Sopenharmony_ci        }
275e41f4b71Sopenharmony_ci      }.height('90%')
276e41f4b71Sopenharmony_ci
277e41f4b71Sopenharmony_ci      Button('Switch Hidden and Show').onClick(() => {
278e41f4b71Sopenharmony_ci        this.isVisible = !(this.isVisible);
279e41f4b71Sopenharmony_ci      })
280e41f4b71Sopenharmony_ci    }
281e41f4b71Sopenharmony_ci  }
282e41f4b71Sopenharmony_ci}
283e41f4b71Sopenharmony_ci```
284e41f4b71Sopenharmony_ci
285e41f4b71Sopenharmony_ci**Example**
286e41f4b71Sopenharmony_ci
287e41f4b71Sopenharmony_ciThe following uses a container to limit the component render scope of conditional rendering.
288e41f4b71Sopenharmony_ci
289e41f4b71Sopenharmony_ci```ts
290e41f4b71Sopenharmony_ci@Entry
291e41f4b71Sopenharmony_ci@Component
292e41f4b71Sopenharmony_cistruct RenderControlWithStack {
293e41f4b71Sopenharmony_ci  @State isVisible: boolean = true;
294e41f4b71Sopenharmony_ci  private data: number[] = [];
295e41f4b71Sopenharmony_ci
296e41f4b71Sopenharmony_ci  aboutToAppear() {
297e41f4b71Sopenharmony_ci    for (let i: number = 0; i < 1000; i++) {
298e41f4b71Sopenharmony_ci      this.data.push(i);
299e41f4b71Sopenharmony_ci    }
300e41f4b71Sopenharmony_ci  }
301e41f4b71Sopenharmony_ci
302e41f4b71Sopenharmony_ci  build() {
303e41f4b71Sopenharmony_ci    Column() {
304e41f4b71Sopenharmony_ci      Stack() {
305e41f4b71Sopenharmony_ci        Scroll() {
306e41f4b71Sopenharmony_ci          Column() {
307e41f4b71Sopenharmony_ci            Stack() { // Set a layer of container for conditional rendering to limit the render scope.
308e41f4b71Sopenharmony_ci              if (this.isVisible) {
309e41f4b71Sopenharmony_ci                Text('New item').fontSize(20)
310e41f4b71Sopenharmony_ci              }
311e41f4b71Sopenharmony_ci            }
312e41f4b71Sopenharmony_ci
313e41f4b71Sopenharmony_ci            ForEach(this.data, (item: number) => {
314e41f4b71Sopenharmony_ci              Text(`Item value: ${item}`).fontSize(20).width('100%').textAlign(TextAlign.Center)
315e41f4b71Sopenharmony_ci            }, (item: number) => item.toString())
316e41f4b71Sopenharmony_ci          }
317e41f4b71Sopenharmony_ci        }
318e41f4b71Sopenharmony_ci      }.height('90%')
319e41f4b71Sopenharmony_ci
320e41f4b71Sopenharmony_ci      Button('Switch Hidden and Show').onClick(() => {
321e41f4b71Sopenharmony_ci        this.isVisible = !(this.isVisible);
322e41f4b71Sopenharmony_ci      })
323e41f4b71Sopenharmony_ci    }
324e41f4b71Sopenharmony_ci  }
325e41f4b71Sopenharmony_ci}
326e41f4b71Sopenharmony_ci```
327e41f4b71Sopenharmony_ci
328e41f4b71Sopenharmony_ci**Effect Comparison**
329e41f4b71Sopenharmony_ci
330e41f4b71Sopenharmony_ciPerform the same steps for the preceding example and nonexample: Click the button to hide the initially visible **\<Text>** component, and then click the button again to show the component. Make sure the interval between showing and hiding the components is long enough for the page rendering to be complete.
331e41f4b71Sopenharmony_ci
332e41f4b71Sopenharmony_ciThe **\<Text>** component in the container is contained in the **if** condition. Once the evaluation result of the **if** condition changes, the component is created or destroyed. In this case, the layout of the **\<Column>** container is affected, and all components in the container, including the **ForEach** module, are re-rendered. As a result, the main thread spends a long time in UI re-rendering.
333e41f4b71Sopenharmony_ci
334e41f4b71Sopenharmony_ciThe following figure shows the performance data when no container is used to limit the component render scope. The **\<Column>** component is marked as a dirty area, and **ForEach** takes 13 ms.
335e41f4b71Sopenharmony_ci
336e41f4b71Sopenharmony_ci![img](./figures/RenderControlWithoutStack.png) 
337e41f4b71Sopenharmony_ci
338e41f4b71Sopenharmony_ciIf a **\<Stack>** component is used to wrap the **\<Text>** component contained in the **if** condition, then only the **\<Text>** component is re-rendered when the evaluation result of the **if** condition changes. This way, the UI re-rendering time of the main thread is reduced.
339e41f4b71Sopenharmony_ci
340e41f4b71Sopenharmony_ciThe following figure shows the performance data when a container is used to limit the component render scope. The **\<Column>** component is not marked as a dirty area, and no time is spent for **ForEach**.
341e41f4b71Sopenharmony_ci
342e41f4b71Sopenharmony_ci![img](./figures/RenderControlWithStack.png) 
343e41f4b71Sopenharmony_ci
344e41f4b71Sopenharmony_ciBy comparing the performance data, we can conclude that, in scenarios where only some components need to be switched between visibility states and the conditions for rendering change frequently, combining conditional rendering with container restrictions can precisely control the component render scope and improve application performance.
345e41f4b71Sopenharmony_ci
346e41f4b71Sopenharmony_ci### Conditional Rendering and Component Reuse
347e41f4b71Sopenharmony_ci
348e41f4b71Sopenharmony_ciIn scenarios where the branches of conditional rendering change repeatedly and the component subtree structure in each branch is complex, consider reusing components for conditional rendering. In the following examples, a custom complex child component **MockComplexSubBranch** is defined to work with conditional rendering.
349e41f4b71Sopenharmony_ci
350e41f4b71Sopenharmony_ci**Nonexample**
351e41f4b71Sopenharmony_ci
352e41f4b71Sopenharmony_ciComponent reuse is not used to implement conditional rendering:
353e41f4b71Sopenharmony_ci
354e41f4b71Sopenharmony_ci```ts
355e41f4b71Sopenharmony_ci@Entry
356e41f4b71Sopenharmony_ci@Component
357e41f4b71Sopenharmony_cistruct IfWithoutReusable {
358e41f4b71Sopenharmony_ci  @State isAlignStyleStart: boolean = true;
359e41f4b71Sopenharmony_ci
360e41f4b71Sopenharmony_ci  build() {
361e41f4b71Sopenharmony_ci    Column() {
362e41f4b71Sopenharmony_ci      Button("Change FlexAlign").onClick(() => {
363e41f4b71Sopenharmony_ci        this.isAlignStyleStart = !this.isAlignStyleStart;
364e41f4b71Sopenharmony_ci      })
365e41f4b71Sopenharmony_ci      Stack() {
366e41f4b71Sopenharmony_ci        if (this.isAlignStyleStart) {
367e41f4b71Sopenharmony_ci          MockComplexSubBranch({ alignStyle: FlexAlign.Start }); // MockComplexSubBranch is implemented without using the component reuse mechanism.
368e41f4b71Sopenharmony_ci        } else {
369e41f4b71Sopenharmony_ci          MockComplexSubBranch({ alignStyle: FlexAlign.End });
370e41f4b71Sopenharmony_ci        }
371e41f4b71Sopenharmony_ci      }
372e41f4b71Sopenharmony_ci    }
373e41f4b71Sopenharmony_ci  }
374e41f4b71Sopenharmony_ci}
375e41f4b71Sopenharmony_ci```
376e41f4b71Sopenharmony_ci
377e41f4b71Sopenharmony_ciThe **MockComplexSubBranch** consists of three **\<Flex>** container components and 200 **\<Text>** components. It is used to simulate a complex subtree structure. The code snippet is as follows:
378e41f4b71Sopenharmony_ci
379e41f4b71Sopenharmony_ci```ts
380e41f4b71Sopenharmony_ci@Component
381e41f4b71Sopenharmony_ciexport struct MockComplexSubBranch {
382e41f4b71Sopenharmony_ci  @State alignStyle: FlexAlign = FlexAlign.Center;
383e41f4b71Sopenharmony_ci
384e41f4b71Sopenharmony_ci  build() {
385e41f4b71Sopenharmony_ci    Column() {
386e41f4b71Sopenharmony_ci      Column({ space: 5 }) {
387e41f4b71Sopenharmony_ci        Text('ComplexSubBranch not reusable').fontSize(9).fontColor(0xCCCCCC).width('90%')
388e41f4b71Sopenharmony_ci        AlignContentFlex({ alignStyle: this.alignStyle });
389e41f4b71Sopenharmony_ci        AlignContentFlex({ alignStyle: this.alignStyle });
390e41f4b71Sopenharmony_ci        AlignContentFlex({ alignStyle: this.alignStyle });
391e41f4b71Sopenharmony_ci      }
392e41f4b71Sopenharmony_ci    }
393e41f4b71Sopenharmony_ci  }
394e41f4b71Sopenharmony_ci}
395e41f4b71Sopenharmony_ci
396e41f4b71Sopenharmony_ci@Component
397e41f4b71Sopenharmony_cistruct AlignContentFlex {
398e41f4b71Sopenharmony_ci  @Link alignStyle: FlexAlign;
399e41f4b71Sopenharmony_ci  private data: number[] = [];
400e41f4b71Sopenharmony_ci
401e41f4b71Sopenharmony_ci  aboutToAppear() {
402e41f4b71Sopenharmony_ci    for (let i: number = 0; i < 200; i++) {
403e41f4b71Sopenharmony_ci      this.data.push(i);
404e41f4b71Sopenharmony_ci    }
405e41f4b71Sopenharmony_ci  }
406e41f4b71Sopenharmony_ci
407e41f4b71Sopenharmony_ci  build() {
408e41f4b71Sopenharmony_ci    Flex({ wrap: FlexWrap.Wrap, alignContent: this.alignStyle }) {
409e41f4b71Sopenharmony_ci      ForEach(this.data, (item: number) => {
410e41f4b71Sopenharmony_ci        Text(`${item % 10}`).width('5%').height(20).backgroundColor(item % 2 === 0 ? 0xF5DEB3 : 0xD2B48C)
411e41f4b71Sopenharmony_ci      }, (item: number) => item.toString())
412e41f4b71Sopenharmony_ci    }.size({ width: '100%', height: 240 }).padding(10).backgroundColor(0xAFEEEE)
413e41f4b71Sopenharmony_ci  }
414e41f4b71Sopenharmony_ci}
415e41f4b71Sopenharmony_ci```
416e41f4b71Sopenharmony_ci
417e41f4b71Sopenharmony_ci**Example**
418e41f4b71Sopenharmony_ci
419e41f4b71Sopenharmony_ciComponent reuse is used to implement conditional rendering:
420e41f4b71Sopenharmony_ci
421e41f4b71Sopenharmony_ci```ts
422e41f4b71Sopenharmony_ci@Entry
423e41f4b71Sopenharmony_ci@Component
424e41f4b71Sopenharmony_cistruct IfWithReusable {
425e41f4b71Sopenharmony_ci  @State isAlignStyleStart: boolean = true;
426e41f4b71Sopenharmony_ci
427e41f4b71Sopenharmony_ci  build() {
428e41f4b71Sopenharmony_ci    Column() {
429e41f4b71Sopenharmony_ci      Button("Change FlexAlign").onClick(() => {
430e41f4b71Sopenharmony_ci        this.isAlignStyleStart = !this.isAlignStyleStart;
431e41f4b71Sopenharmony_ci      })
432e41f4b71Sopenharmony_ci      Stack() {
433e41f4b71Sopenharmony_ci        if (this.isAlignStyleStart) {
434e41f4b71Sopenharmony_ci          MockComplexSubBranch({ alignStyle: FlexAlign.Start }); // MockComplexSubBranch is implemented using the component reuse mechanism.
435e41f4b71Sopenharmony_ci        } else {
436e41f4b71Sopenharmony_ci          MockComplexSubBranch({ alignStyle: FlexAlign.End });
437e41f4b71Sopenharmony_ci        }
438e41f4b71Sopenharmony_ci      }
439e41f4b71Sopenharmony_ci    }
440e41f4b71Sopenharmony_ci  }
441e41f4b71Sopenharmony_ci}
442e41f4b71Sopenharmony_ci```
443e41f4b71Sopenharmony_ci
444e41f4b71Sopenharmony_ciThe implementation of **MockComplexSubBranch** is as follows. The **AlignContentFlex** code is the same as that in the preceding code snippet and therefore not included here.
445e41f4b71Sopenharmony_ci
446e41f4b71Sopenharmony_ci```ts
447e41f4b71Sopenharmony_ci@Component
448e41f4b71Sopenharmony_ci@Reusable // Add the @Reusable decorator to declare that the component can be reused.
449e41f4b71Sopenharmony_ciexport struct MockComplexSubBranch {
450e41f4b71Sopenharmony_ci  @State alignStyle: FlexAlign = FlexAlign.Center;
451e41f4b71Sopenharmony_ci
452e41f4b71Sopenharmony_ci  aboutToReuse(params: ESObject) {// Called when the component is about to be added from the reuse cache to the component tree.
453e41f4b71Sopenharmony_ci    this.alignStyle = params.alignStyle;
454e41f4b71Sopenharmony_ci  }
455e41f4b71Sopenharmony_ci
456e41f4b71Sopenharmony_ci  build() {
457e41f4b71Sopenharmony_ci    Column() {
458e41f4b71Sopenharmony_ci      Column({ space: 5 }) {
459e41f4b71Sopenharmony_ci        Text('ComplexSubBranch reusable').fontSize(9).fontColor(0xCCCCCC).width('90%')
460e41f4b71Sopenharmony_ci        AlignContentFlex({ alignStyle: this.alignStyle });
461e41f4b71Sopenharmony_ci        AlignContentFlex({ alignStyle: this.alignStyle });
462e41f4b71Sopenharmony_ci        AlignContentFlex({ alignStyle: this.alignStyle });
463e41f4b71Sopenharmony_ci      }
464e41f4b71Sopenharmony_ci    }
465e41f4b71Sopenharmony_ci  }
466e41f4b71Sopenharmony_ci}
467e41f4b71Sopenharmony_ci
468e41f4b71Sopenharmony_ci```
469e41f4b71Sopenharmony_ci
470e41f4b71Sopenharmony_ci**Effect Comparison**
471e41f4b71Sopenharmony_ci
472e41f4b71Sopenharmony_ciPerform the same steps for the preceding example and nonexample: Click the button to change alignment of the **\<Text>** component in the **\<Flex>** container along the main axis. Make sure the interval between alignment switching is long enough for the page rendering to be complete.
473e41f4b71Sopenharmony_ci
474e41f4b71Sopenharmony_ciThe subtree structure of the **MockComplexSubBranch** component in each branch is complex. In this case, when the button is repeatedly clicked to change the branch, a large number of components are destroyed and created. As a result, if components are not reused, UI re-rendering can be significantly time-consuming. As shown below, the rendering of the application **Index** page takes 180 ms.
475e41f4b71Sopenharmony_ci
476e41f4b71Sopenharmony_ci![img](./figures/IfWithoutReusable.png) 
477e41f4b71Sopenharmony_ci
478e41f4b71Sopenharmony_ciIf components are reused during conditional rendering, the UI re-rendering time can be greatly shortened. As shown below, the rendering of the application **Index** page takes as short as 14 ms.
479e41f4b71Sopenharmony_ci
480e41f4b71Sopenharmony_ci![img](./figures/IfWithReusable.png) 
481e41f4b71Sopenharmony_ci
482e41f4b71Sopenharmony_ciIn sum, if the component subtree structure is complex and the conditions for rendering change frequently, it is recommended that you use conditional rendering with the component reuse mechanism to improve application performance.
483