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 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 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 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 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 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 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 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 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