1e41f4b71Sopenharmony_ci# Improving Layout Performance
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci## Background
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ciLayouts in the user interface (UI) are a key part of interactions between users and your application. A UI with diverse, well-designed layouts is more enjoyable to interact with. Yet, if poorly implemented, layouts can also lead to performance bottlenecks. Poor layouts may still appear, on the surface, attractive, but the huge overhead underneath – resulting from transition layout calculation and unnecessary nesting, can undermine performance. This document provides tips for optimizing the layout structure, with primary focus on most common layouts and their use cases.
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ci## Common Layouts
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ciThe layout defines how components are laid out in the UI. ArkUI offers a diverse array of layouts. Besides the basic layouts – [linear](../ui/arkts-layout-development-linear.md) ([\<Row>](../reference/arkui-ts/ts-container-row.md)/[\<Column>](../reference/arkui-ts/ts-container-column.md)), [stack](../ui/arkts-layout-development-stack-layout.md) ([\<Stack>](../reference/arkui-ts/ts-container-stack.md)), [flex](../ui/arkts-layout-development-flex-layout.md) ([\<Flex>](../reference/arkui-ts/ts-container-flex.md)), [relative](../ui/arkts-layout-development-relative-layout.md) ([\<RelativeContainer>](../reference/arkui-ts/ts-container-relativecontainer.md)), and [responsive grid](../ui/arkts-layout-development-grid-layout.md) ([\<GridCol>](../reference/arkui-ts/ts-container-gridcol.md)), you also have access to the advanced [list](../ui/arkts-layout-development-create-list.md) ([\<List>](../reference/arkui-ts/ts-container-list.md)), [grid](../ui/arkts-layout-development-create-grid.md) ([\<Grid>](../reference/arkui-ts/ts-container-grid.md)/[\<GridItem>](../reference/arkui-ts/ts-container-griditem.md)), and [swiper](../ui/arkts-layout-development-create-looping.md) ([\<Swiper>](../reference/arkui-ts/ts-container-swiper.md)) layouts.
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci## Optimizing Layout Structure
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ci### Reducing Nesting
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ciCompared with a flat layout, a deep layout with too much nesting means more time spent on node creation and layout. For optimized layout hierarchies, avoid redundant nesting or flatten the layout.
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ci**Avoiding Redundant Nesting**
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ciRedundant nesting results in unnecessary component nodes and deepens the hierarchy of the component tree. For example, if internal and external containers have the same layout direction, the external container can be used in place of the internal one to deliver the same layout effect. In this case, the redundant container can be removed to reduce nesting.
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ciNonexample:
22e41f4b71Sopenharmony_ci
23e41f4b71Sopenharmony_ciThe following uses the **\<Grid>** component to implement a grid, outside of which three layers of stack containers with different attributes are deployed.
24e41f4b71Sopenharmony_ci
25e41f4b71Sopenharmony_ci```ts
26e41f4b71Sopenharmony_ci@Entry
27e41f4b71Sopenharmony_ci@Component
28e41f4b71Sopenharmony_cistruct AspectRatioExample12 {
29e41f4b71Sopenharmony_ci    @State children: Number[] = Array.from(Array<number>(900), (v, k) => k);
30e41f4b71Sopenharmony_ci    
31e41f4b71Sopenharmony_ci    build() {
32e41f4b71Sopenharmony_ci      Scroll() {
33e41f4b71Sopenharmony_ci      Grid() {
34e41f4b71Sopenharmony_ci        ForEach(this.children, (item: Number[]) => {
35e41f4b71Sopenharmony_ci          GridItem() {
36e41f4b71Sopenharmony_ci            Stack() {  
37e41f4b71Sopenharmony_ci              Stack() {  
38e41f4b71Sopenharmony_ci                Stack() {  
39e41f4b71Sopenharmony_ci                  Text(item.toString())  
40e41f4b71Sopenharmony_ci                }.size({ width: "100%"})  
41e41f4b71Sopenharmony_ci              }.backgroundColor(Color.Yellow)  
42e41f4b71Sopenharmony_ci            }.backgroundColor(Color.Pink)  
43e41f4b71Sopenharmony_ci          }  
44e41f4b71Sopenharmony_ci        }, (item: string) => item)  
45e41f4b71Sopenharmony_ci      }  
46e41f4b71Sopenharmony_ci      .columnsTemplate('1fr 1fr 1fr 1fr')  
47e41f4b71Sopenharmony_ci      .columnsGap(0)  
48e41f4b71Sopenharmony_ci      .rowsGap(0)  
49e41f4b71Sopenharmony_ci      .size({ width: "100%", height: "100%" })  
50e41f4b71Sopenharmony_ci    }  
51e41f4b71Sopenharmony_ci  }  
52e41f4b71Sopenharmony_ci}
53e41f4b71Sopenharmony_ci
54e41f4b71Sopenharmony_ci```
55e41f4b71Sopenharmony_ci
56e41f4b71Sopenharmony_ciA review of the component tree structure reveals that, the desirable UI effect can be equally achieved by the attribute settings of the grid items. In this sense, the three-layer stack containers are redundant and can be removed.
57e41f4b71Sopenharmony_ci
58e41f4b71Sopenharmony_ci
59e41f4b71Sopenharmony_ci```
60e41f4b71Sopenharmony_ci└─┬Scroll
61e41f4b71Sopenharmony_ci  └─┬Grid
62e41f4b71Sopenharmony_ci    ├─┬GridItem
63e41f4b71Sopenharmony_ci    │ └─┬Stack
64e41f4b71Sopenharmony_ci    │   └─┬Stack
65e41f4b71Sopenharmony_ci    │     └─┬Stack
66e41f4b71Sopenharmony_ci    │       └──Text
67e41f4b71Sopenharmony_ci    ├──GridItem
68e41f4b71Sopenharmony_ci    ├──GridItem
69e41f4b71Sopenharmony_ci```
70e41f4b71Sopenharmony_ci
71e41f4b71Sopenharmony_ciExample:
72e41f4b71Sopenharmony_ci
73e41f4b71Sopenharmony_ciIn the following code, by removing redundant nesting of stack containers, the number of child components in each grid item is three less than that in the previous example.
74e41f4b71Sopenharmony_ci
75e41f4b71Sopenharmony_ci```ts
76e41f4b71Sopenharmony_ci@Entry  
77e41f4b71Sopenharmony_ci@Component  
78e41f4b71Sopenharmony_cistruct AspectRatioExample11 {  
79e41f4b71Sopenharmony_ci  @State children: Number[] = Array.from(Array<number>(900), (v, k) => k);  
80e41f4b71Sopenharmony_ci  
81e41f4b71Sopenharmony_ci  build() {  
82e41f4b71Sopenharmony_ci    Scroll() {  
83e41f4b71Sopenharmony_ci      Grid() {  
84e41f4b71Sopenharmony_ci        ForEach(this.children, (item: Number[]) => {  
85e41f4b71Sopenharmony_ci          GridItem() {  
86e41f4b71Sopenharmony_ci            Text(item.toString())  
87e41f4b71Sopenharmony_ci          }.backgroundColor(Color.Yellow)  
88e41f4b71Sopenharmony_ci        }, (item: string) => item)  
89e41f4b71Sopenharmony_ci      }  
90e41f4b71Sopenharmony_ci      .columnsTemplate('1fr 1fr 1fr 1fr')  
91e41f4b71Sopenharmony_ci      .columnsGap(0)  
92e41f4b71Sopenharmony_ci      .rowsGap(0)  
93e41f4b71Sopenharmony_ci      .size({ width: "100%", height: "100%" })  
94e41f4b71Sopenharmony_ci    }  
95e41f4b71Sopenharmony_ci  }  
96e41f4b71Sopenharmony_ci}
97e41f4b71Sopenharmony_ci```
98e41f4b71Sopenharmony_ci
99e41f4b71Sopenharmony_ciThe component tree structure is as follows:
100e41f4b71Sopenharmony_ci
101e41f4b71Sopenharmony_ci```
102e41f4b71Sopenharmony_ci└─┬Scroll
103e41f4b71Sopenharmony_ci  └─┬Grid
104e41f4b71Sopenharmony_ci    ├─┬GridItem
105e41f4b71Sopenharmony_ci    │ └──Text
106e41f4b71Sopenharmony_ci    ├──GridItem
107e41f4b71Sopenharmony_ci    ├──GridItem
108e41f4b71Sopenharmony_ci```
109e41f4b71Sopenharmony_ci
110e41f4b71Sopenharmony_ci**Flattening Layout**
111e41f4b71Sopenharmony_ci
112e41f4b71Sopenharmony_ciIn implementing an adaptive layout, use of the **\<Flex>** component can cause multi-level nesting. In this scenario, you are advised to use **\<RelativeContainer>** to flatten the layout to effectively reduce nesting and shorten the component creation time.
113e41f4b71Sopenharmony_ci
114e41f4b71Sopenharmony_ciThe figure below shows an adaptive UI.
115e41f4b71Sopenharmony_ci
116e41f4b71Sopenharmony_ci![layout-ui-view](figures/layout-ui-view.png)
117e41f4b71Sopenharmony_ci
118e41f4b71Sopenharmony_ciNonexample:
119e41f4b71Sopenharmony_ci
120e41f4b71Sopenharmony_ciThe following code uses a linear layout to implement the UI shown above:
121e41f4b71Sopenharmony_ci
122e41f4b71Sopenharmony_ci```ts
123e41f4b71Sopenharmony_ci@Entry  
124e41f4b71Sopenharmony_ci@Component  
125e41f4b71Sopenharmony_cistruct MyComponent {  
126e41f4b71Sopenharmony_ci  build() {
127e41f4b71Sopenharmony_ci    Row() {  
128e41f4b71Sopenharmony_ci      Column() {  
129e41f4b71Sopenharmony_ci        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {  
130e41f4b71Sopenharmony_ci          Text ('J') 
131e41f4b71Sopenharmony_ci          // For details about the attribute parameters, see the example. 
132e41f4b71Sopenharmony_ci        }  
133e41f4b71Sopenharmony_ci        .width("40vp")  
134e41f4b71Sopenharmony_ci        .height("40vp")  
135e41f4b71Sopenharmony_ci      }.height("100%").justifyContent(FlexAlign.Center)  
136e41f4b71Sopenharmony_ci      //body  
137e41f4b71Sopenharmony_ci      Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start }) {  
138e41f4b71Sopenharmony_ci          Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center }) {  
139e41f4b71Sopenharmony_ci          Flex({ direction: FlexDirection.Row,  
140e41f4b71Sopenharmony_ci            justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {  
141e41f4b71Sopenharmony_ci            //Phone number or first name  
142e41f4b71Sopenharmony_ci            Text('John') 
143e41f4b71Sopenharmony_ci             // For details about the attribute parameters, see the example. 
144e41f4b71Sopenharmony_ci
145e41f4b71Sopenharmony_ci            //Date Time  
146e41f4b71Sopenharmony_ci            Text ('2 min ago') 
147e41f4b71Sopenharmony_ci             // For details about the attribute parameters, see the example.
148e41f4b71Sopenharmony_ci             }  
149e41f4b71Sopenharmony_ci          .width("100%").height(22)  
150e41f4b71Sopenharmony_ci  
151e41f4b71Sopenharmony_ci          Row() {  
152e41f4b71Sopenharmony_ci            Text() {  
153e41f4b71Sopenharmony_ci              //Content Abbreviations for Latest News  
154e41f4b71Sopenharmony_ci              Span('Hello World'.replace(new RegExp("/[\r\n]/g"), " "))  
155e41f4b71Sopenharmony_ci                .fontSize("14fp")  
156e41f4b71Sopenharmony_ci                .fontColor('# 66182431')  
157e41f4b71Sopenharmony_ci            }  
158e41f4b71Sopenharmony_ci            .maxLines(1)  
159e41f4b71Sopenharmony_ci            .textOverflow({ overflow: TextOverflow.Ellipsis })  
160e41f4b71Sopenharmony_ci          }  
161e41f4b71Sopenharmony_ci          .alignSelf(ItemAlign.Start)  
162e41f4b71Sopenharmony_ci          .alignItems(VerticalAlign.Top)  
163e41f4b71Sopenharmony_ci          .width("100%")  
164e41f4b71Sopenharmony_ci          .height(19)  
165e41f4b71Sopenharmony_ci          .margin({ top: "2vp" })  
166e41f4b71Sopenharmony_ci        }.width("100%")  
167e41f4b71Sopenharmony_ci        .height("100%")  
168e41f4b71Sopenharmony_ci      }  
169e41f4b71Sopenharmony_ci      .layoutWeight(1)  
170e41f4b71Sopenharmony_ci      .height("100%")  
171e41f4b71Sopenharmony_ci      .padding({ left: "12vp" })  
172e41f4b71Sopenharmony_ci    }  
173e41f4b71Sopenharmony_ci    .alignItems(VerticalAlign.Top)  
174e41f4b71Sopenharmony_ci    .width("100%")  
175e41f4b71Sopenharmony_ci    .height("100%")  
176e41f4b71Sopenharmony_ci  }  
177e41f4b71Sopenharmony_ci}
178e41f4b71Sopenharmony_ci```
179e41f4b71Sopenharmony_ci
180e41f4b71Sopenharmony_ciThe component tree structure is as follows:
181e41f4b71Sopenharmony_ci
182e41f4b71Sopenharmony_ci```
183e41f4b71Sopenharmony_ci└─┬Row
184e41f4b71Sopenharmony_ci  ├──┬Column
185e41f4b71Sopenharmony_ci  │  └─┬Flex
186e41f4b71Sopenharmony_ci  │    └──Text
187e41f4b71Sopenharmony_ci  └─┬Flex
188e41f4b71Sopenharmony_ci    └─┬Flex
189e41f4b71Sopenharmony_ci      │ └─┬Flex
190e41f4b71Sopenharmony_ci      │   ├──Text
191e41f4b71Sopenharmony_ci      │   └──Text
192e41f4b71Sopenharmony_ci      └─┬Row
193e41f4b71Sopenharmony_ci        └──Text
194e41f4b71Sopenharmony_ci```
195e41f4b71Sopenharmony_ci
196e41f4b71Sopenharmony_ciTo place four elements in proper positions, 11 components are used with a tree depth of 5, which is actually unreasonable.
197e41f4b71Sopenharmony_ci
198e41f4b71Sopenharmony_ciThe figure below illustrates the layout of the elements.
199e41f4b71Sopenharmony_ci
200e41f4b71Sopenharmony_ci![Input picture description](figures/layout-relative-view.png)
201e41f4b71Sopenharmony_ci
202e41f4b71Sopenharmony_ciExample:
203e41f4b71Sopenharmony_ci
204e41f4b71Sopenharmony_ciThe figure above shows a clear relative layout relationship. In light of this, a **\<RelativeContainer>** can be adopted to improve performance. Below is the specific code implementation.
205e41f4b71Sopenharmony_ci
206e41f4b71Sopenharmony_ci```ts
207e41f4b71Sopenharmony_ci@Entry  
208e41f4b71Sopenharmony_ci@Component  
209e41f4b71Sopenharmony_cistruct MyComponent {  
210e41f4b71Sopenharmony_ci  build() {  
211e41f4b71Sopenharmony_ci    Row() {  
212e41f4b71Sopenharmony_ci      RelativeContainer() {  
213e41f4b71Sopenharmony_ci        Text ('J') 
214e41f4b71Sopenharmony_ci          .fontSize('20.0vp')  
215e41f4b71Sopenharmony_ci          .fontWeight(FontWeight.Bold)  
216e41f4b71Sopenharmony_ci          .fontColor(Color.White)  
217e41f4b71Sopenharmony_ci          .height('40vp')  
218e41f4b71Sopenharmony_ci          .width('40vp')  
219e41f4b71Sopenharmony_ci          .textAlign(TextAlign.Center)  
220e41f4b71Sopenharmony_ci          .clip(new Circle({ width: '40vp', height: '40vp' }))  
221e41f4b71Sopenharmony_ci          .backgroundColor(Color.Green)  
222e41f4b71Sopenharmony_ci          .alignRules({  
223e41f4b71Sopenharmony_ci            center: { anchor: "__container__", align: VerticalAlign.Center },  
224e41f4b71Sopenharmony_ci            left: { anchor: "__container__", align: HorizontalAlign.Start }  
225e41f4b71Sopenharmony_ci          })  
226e41f4b71Sopenharmony_ci          .id('head')  
227e41f4b71Sopenharmony_ci        Text('John') 
228e41f4b71Sopenharmony_ci          .fontSize('16.0fp')  
229e41f4b71Sopenharmony_ci          .textOverflow({ overflow: TextOverflow.Ellipsis })  
230e41f4b71Sopenharmony_ci          .fontColor('# ff182431')  
231e41f4b71Sopenharmony_ci          .maxLines(1)  
232e41f4b71Sopenharmony_ci          .fontWeight(FontWeight.Medium)  
233e41f4b71Sopenharmony_ci          .padding({ left: '12vp' })  
234e41f4b71Sopenharmony_ci          .height(22)  
235e41f4b71Sopenharmony_ci          .alignRules({  
236e41f4b71Sopenharmony_ci            top: { anchor: 'head', align: VerticalAlign.Top },  
237e41f4b71Sopenharmony_ci            left: { anchor: 'head', align: HorizontalAlign.End }  
238e41f4b71Sopenharmony_ci          })  
239e41f4b71Sopenharmony_ci          .id('name')  
240e41f4b71Sopenharmony_ci        Text ('2 min ago') 
241e41f4b71Sopenharmony_ci          .fontColor('# 66182431')  
242e41f4b71Sopenharmony_ci          .fontSize('12fp')  
243e41f4b71Sopenharmony_ci          .maxLines(1)  
244e41f4b71Sopenharmony_ci          .height(22)  
245e41f4b71Sopenharmony_ci          .alignRules({  
246e41f4b71Sopenharmony_ci            top: { anchor: 'head', align: VerticalAlign.Top },  
247e41f4b71Sopenharmony_ci            right: { anchor: '__container__', align: HorizontalAlign.End }  
248e41f4b71Sopenharmony_ci          })  
249e41f4b71Sopenharmony_ci          .id("time")  
250e41f4b71Sopenharmony_ci        Text() {  
251e41f4b71Sopenharmony_ci          //Content Abbreviations for Latest News  
252e41f4b71Sopenharmony_ci          Span('Hello World'.replace(new RegExp("/[\r\n]/g"), " "))  
253e41f4b71Sopenharmony_ci            .fontSize('14fp')  
254e41f4b71Sopenharmony_ci            .fontColor('# 66182431')  
255e41f4b71Sopenharmony_ci        }  
256e41f4b71Sopenharmony_ci        .maxLines(1)  
257e41f4b71Sopenharmony_ci        .textOverflow({ overflow: TextOverflow.Ellipsis })  
258e41f4b71Sopenharmony_ci        .width('100%')  
259e41f4b71Sopenharmony_ci        .height(19)  
260e41f4b71Sopenharmony_ci        .margin({ top: '2vp' })  
261e41f4b71Sopenharmony_ci        .padding({ left: '12vp' })  
262e41f4b71Sopenharmony_ci        .alignRules({  
263e41f4b71Sopenharmony_ci          top: { anchor: 'name', align: VerticalAlign.Bottom },  
264e41f4b71Sopenharmony_ci          left: { anchor: 'head', align: HorizontalAlign.End }  
265e41f4b71Sopenharmony_ci        })  
266e41f4b71Sopenharmony_ci        .id('content')  
267e41f4b71Sopenharmony_ci      }  
268e41f4b71Sopenharmony_ci      .width('100%').height('100%')  
269e41f4b71Sopenharmony_ci      .border({ width: 1, color: "# 6699FF" })  
270e41f4b71Sopenharmony_ci    }  
271e41f4b71Sopenharmony_ci    .height('100%')  
272e41f4b71Sopenharmony_ci  }  
273e41f4b71Sopenharmony_ci}
274e41f4b71Sopenharmony_ci```
275e41f4b71Sopenharmony_ci
276e41f4b71Sopenharmony_ciThe new layout, which delivers the same effect as the previous deep layout, has three less component layers and six less components.
277e41f4b71Sopenharmony_ci
278e41f4b71Sopenharmony_ci```
279e41f4b71Sopenharmony_ci└─┬RelativeContainer
280e41f4b71Sopenharmony_ci  ├──Text
281e41f4b71Sopenharmony_ci  ├──Text
282e41f4b71Sopenharmony_ci  ├──Text
283e41f4b71Sopenharmony_ci  └──Text
284e41f4b71Sopenharmony_ci```
285e41f4b71Sopenharmony_ci
286e41f4b71Sopenharmony_ciAs shown in the preceding examples, the flattened layout presents clearer logic design, avoiding components that are not involved in drawing for better performance and less memory usage. By flattening the layout, you collapse the hierarchy levels of a deep UI tree and re-arrange content into under one top node. The figure below illustrates how layout flattening helps remove the redundant layout nodes.
287e41f4b71Sopenharmony_ci
288e41f4b71Sopenharmony_ci![layout-relative-introduce](figures/layout-relative-introduce.png)
289e41f4b71Sopenharmony_ci
290e41f4b71Sopenharmony_ciTools available for flattening the layout include, among others, the [\<RelativeContainer>](../reference/arkui-ts/ts-container-relativecontainer.md) component, [\<Grid>](../reference/arkui-ts/ts-container-grid.md) component, [absolute location](../reference/arkui-ts/ts-universal-attributes-location.md), and [custom layout](../reference/arkui-ts/ts-custom-component-lifecycle.md).
291e41f4b71Sopenharmony_ci
292e41f4b71Sopenharmony_ci### Using High-Performance Layout Components
293e41f4b71Sopenharmony_ci
294e41f4b71Sopenharmony_ci**Replacing Flex Containers with Columns/Rows**
295e41f4b71Sopenharmony_ci
296e41f4b71Sopenharmony_ciIf you are using the flex container to merely implement a horizontal or vertical layout, the **\<Row>** and **\<Column>** components are better choices in terms of rendering performance benefits. For details about the impact of the flex container on performance, see [Flex Layout Performance Improvement](flex-development-performance-boost.md).
297e41f4b71Sopenharmony_ci
298e41f4b71Sopenharmony_ciFor details about how to replace the flex container components with **\<Row>** and **\<Column>** components to avoid secondary rendering, see [More Performance Improvement Methods](arkts-performance-improvement-recommendation.md).
299e41f4b71Sopenharmony_ci
300e41f4b71Sopenharmony_ci**Reducing Use of if/else**
301e41f4b71Sopenharmony_ci
302e41f4b71Sopenharmony_ciIn the build function of ArkUI, **if/else** is also regarded as a component and a node in the component tree. In scenarios where the basic layout remains unchanged, reduce the use of if/else if modifying attribute settings can achieve the same purpose – present different GUI content under different conditions. The use of **if/else** not only adds a layer of nodes, but might also result in re-layout and re-render.
303e41f4b71Sopenharmony_ci
304e41f4b71Sopenharmony_ciNonexample:
305e41f4b71Sopenharmony_ci
306e41f4b71Sopenharmony_ciIn the following code, the value of **isVisible** is used to control the visibility of the **\<Image>** component. As a result, the **\<Image>** component is continuously created and destroyed during the selection switchover.
307e41f4b71Sopenharmony_ci
308e41f4b71Sopenharmony_ci```ts
309e41f4b71Sopenharmony_ci@Entry  
310e41f4b71Sopenharmony_ci@Component  
311e41f4b71Sopenharmony_cistruct TopicItem {  
312e41f4b71Sopenharmony_ci  @State isVisible : Boolean = true;  
313e41f4b71Sopenharmony_ci  
314e41f4b71Sopenharmony_ci  build() {  
315e41f4b71Sopenharmony_ci    Stack() {  
316e41f4b71Sopenharmony_ci      Column(){  
317e41f4b71Sopenharmony_ci        if (this.isVisible) {  
318e41f4b71Sopenharmony_ci          Image($r('app.media.icon')).width('25%').height('12.5%')  
319e41f4b71Sopenharmony_ci          Image($r('app.media.icon')).width('25%').height('12.5%')  
320e41f4b71Sopenharmony_ci          Image($r('app.media.icon')).width('25%').height('12.5%')  
321e41f4b71Sopenharmony_ci          Image($r('app.media.icon')).width('25%').height('12.5%')  
322e41f4b71Sopenharmony_ci        }  
323e41f4b71Sopenharmony_ci      }  
324e41f4b71Sopenharmony_ci      Column() {  
325e41f4b71Sopenharmony_ci        Row().width(300).height(200).backgroundColor(Color.Pink)  
326e41f4b71Sopenharmony_ci      }  
327e41f4b71Sopenharmony_ci    }  
328e41f4b71Sopenharmony_ci  }  
329e41f4b71Sopenharmony_ci}
330e41f4b71Sopenharmony_ci```
331e41f4b71Sopenharmony_ci
332e41f4b71Sopenharmony_ciBelow are the component trees at different values of **isVisible**.
333e41f4b71Sopenharmony_ci
334e41f4b71Sopenharmony_ci```
335e41f4b71Sopenharmony_ciComponent tree when **isVisible** is **true**:
336e41f4b71Sopenharmony_ci└─┬Stack
337e41f4b71Sopenharmony_ci  ├─┬Column
338e41f4b71Sopenharmony_ci  │ ├──Image
339e41f4b71Sopenharmony_ci  │ ├──Image
340e41f4b71Sopenharmony_ci  │ ├──Image
341e41f4b71Sopenharmony_ci  │ └──Image
342e41f4b71Sopenharmony_ci  └─┬Column
343e41f4b71Sopenharmony_ci    └──Row
344e41f4b71Sopenharmony_ci
345e41f4b71Sopenharmony_ciComponent tree when **isVisible** is **false**:
346e41f4b71Sopenharmony_ci└─┬Stack
347e41f4b71Sopenharmony_ci  ├──Column
348e41f4b71Sopenharmony_ci  └─┬Column
349e41f4b71Sopenharmony_ci    └──Row
350e41f4b71Sopenharmony_ci```
351e41f4b71Sopenharmony_ci
352e41f4b71Sopenharmony_ciExample:
353e41f4b71Sopenharmony_ci
354e41f4b71Sopenharmony_ciIn the following example, the **visibility** attribute is used to control the visibility of the **\<Image>** component, avoiding the re-layout and re-rendered caused by **if/else**.
355e41f4b71Sopenharmony_ci
356e41f4b71Sopenharmony_ci```ts
357e41f4b71Sopenharmony_ci@Entry  
358e41f4b71Sopenharmony_ci@Component  
359e41f4b71Sopenharmony_cistruct TopicItem {  
360e41f4b71Sopenharmony_ci  @State isVisible : Boolean = true;  
361e41f4b71Sopenharmony_ci  
362e41f4b71Sopenharmony_ci  build() {  
363e41f4b71Sopenharmony_ci    Stack() {  
364e41f4b71Sopenharmony_ci      Column(){  
365e41f4b71Sopenharmony_ci          Image($r('app.media.icon'))  
366e41f4b71Sopenharmony_ci            .width('25%').height('12.5%').visibility(this.isVisible ? Visibility.Visible : Visibility.None)  
367e41f4b71Sopenharmony_ci          Image($r('app.media.icon'))  
368e41f4b71Sopenharmony_ci            .width('25%').height('12.5%').visibility(this.isVisible ? Visibility.Visible : Visibility.None)  
369e41f4b71Sopenharmony_ci          Image($r('app.media.icon'))  
370e41f4b71Sopenharmony_ci            .width('25%').height('12.5%').visibility(this.isVisible ? Visibility.Visible : Visibility.None)  
371e41f4b71Sopenharmony_ci          Image($r('app.media.icon'))  
372e41f4b71Sopenharmony_ci            .width('25%').height('12.5%').visibility(this.isVisible ? Visibility.Visible : Visibility.None)  
373e41f4b71Sopenharmony_ci      }  
374e41f4b71Sopenharmony_ci      Column() {  
375e41f4b71Sopenharmony_ci        Row().width(300).height(200).backgroundColor(Color.Pink)  
376e41f4b71Sopenharmony_ci      }  
377e41f4b71Sopenharmony_ci    }  
378e41f4b71Sopenharmony_ci  }  
379e41f4b71Sopenharmony_ci}
380e41f4b71Sopenharmony_ci```
381e41f4b71Sopenharmony_ci
382e41f4b71Sopenharmony_ciNote: The aforementioned recommendation is provided in regard of performance. If memory is more of a concern, use **if/else** instead.
383e41f4b71Sopenharmony_ci
384e41f4b71Sopenharmony_ci## Reducing Layout Time
385e41f4b71Sopenharmony_ci
386e41f4b71Sopenharmony_ciCompared with a flat layout, a deep layout with too much nesting means more time spent on node creation and layout. For optimized layout hierarchies, avoid redundant nesting or flatten the layout.
387e41f4b71Sopenharmony_ci
388e41f4b71Sopenharmony_ciNonexample:
389e41f4b71Sopenharmony_ci
390e41f4b71Sopenharmony_ciThe following uses a linear layout, which takes 166 ms 313 us.
391e41f4b71Sopenharmony_ci
392e41f4b71Sopenharmony_ci```ts
393e41f4b71Sopenharmony_ci
394e41f4b71Sopenharmony_ciimport measure from '@ohos.measure';
395e41f4b71Sopenharmony_ciimport prompt from '@ohos.prompt';
396e41f4b71Sopenharmony_ci
397e41f4b71Sopenharmony_ci@Entry
398e41f4b71Sopenharmony_ci@Component
399e41f4b71Sopenharmony_cistruct PerformanceRelative {
400e41f4b71Sopenharmony_ci  @State message: string = 'Hello World'
401e41f4b71Sopenharmony_ci  @State textWidth: string = "";
402e41f4b71Sopenharmony_ci
403e41f4b71Sopenharmony_ci  build() {
404e41f4b71Sopenharmony_ci    Column() {
405e41f4b71Sopenharmony_ci      Image($r("app.media.app_icon")).width("100%").height(300).margin({ bottom: 20 })
406e41f4b71Sopenharmony_ci      Row() {
407e41f4b71Sopenharmony_ci        Blank()
408e41f4b71Sopenharmony_ci        Column() {
409e41f4b71Sopenharmony_ci          Image($r("app.media.app_icon")).margin({ bottom: 4 }).width(40).aspectRatio(1)
410e41f4b71Sopenharmony_ci          Text("Name")
411e41f4b71Sopenharmony_ci        }.margin({ left: 8, right: 8 })
412e41f4b71Sopenharmony_ci      }.position({ y: 280 }).width("100%")
413e41f4b71Sopenharmony_ci      // Empty row
414e41f4b71Sopenharmony_ci      Row().height(this.textWidth)
415e41f4b71Sopenharmony_ci      Column() {
416e41f4b71Sopenharmony_ci        Row() {
417e41f4b71Sopenharmony_ci          Text("Singapore").fontSize(20).fontWeight(FontWeight.Bolder)
418e41f4b71Sopenharmony_ci            .margin(8)
419e41f4b71Sopenharmony_ci            .textAlign(TextAlign.Start)
420e41f4b71Sopenharmony_ci        }.width("100%").justifyContent(FlexAlign.Start)
421e41f4b71Sopenharmony_ci
422e41f4b71Sopenharmony_ci        Flex({ alignItems: ItemAlign.Center }) {
423e41f4b71Sopenharmony_ci          Text("Camera").flexShrink(0)
424e41f4b71Sopenharmony_ci            .margin({ right: 8 })
425e41f4b71Sopenharmony_ci          TextInput()
426e41f4b71Sopenharmony_ci        }.margin(8)
427e41f4b71Sopenharmony_ci
428e41f4b71Sopenharmony_ci        Flex({ alignItems: ItemAlign.Center }) {
429e41f4b71Sopenharmony_ci          Text("Settings").flexShrink(0)
430e41f4b71Sopenharmony_ci            .margin({ right: 8 })
431e41f4b71Sopenharmony_ci          TextInput()
432e41f4b71Sopenharmony_ci        }.margin(8)
433e41f4b71Sopenharmony_ci
434e41f4b71Sopenharmony_ci        Row() {
435e41f4b71Sopenharmony_ci          Column() {
436e41f4b71Sopenharmony_ci            Image($r("app.media.app_icon")).width(80).aspectRatio(1).margin({ bottom: 8 })
437e41f4b71Sopenharmony_ci            Text("Description")
438e41f4b71Sopenharmony_ci          }.margin(8)
439e41f4b71Sopenharmony_ci
440e41f4b71Sopenharmony_ci          Column() {
441e41f4b71Sopenharmony_ci            Text("Title").fontWeight(FontWeight.Bold).margin({ bottom: 8 })
442e41f4b71Sopenharmony_ci            Text("Long Text")
443e41f4b71Sopenharmony_ci          }.margin(8).layoutWeight(1).alignItems(HorizontalAlign.Start)
444e41f4b71Sopenharmony_ci        }.margin(8).width("100%").alignItems(VerticalAlign.Top)
445e41f4b71Sopenharmony_ci      }.layoutWeight(1)
446e41f4b71Sopenharmony_ci
447e41f4b71Sopenharmony_ci      Flex({ justifyContent: FlexAlign.End }) {
448e41f4b71Sopenharmony_ci        Button("Upload").margin(8)
449e41f4b71Sopenharmony_ci        Button("Discard").margin(8)
450e41f4b71Sopenharmony_ci      }
451e41f4b71Sopenharmony_ci    }
452e41f4b71Sopenharmony_ci    .width("100%").height("100%")
453e41f4b71Sopenharmony_ci  }
454e41f4b71Sopenharmony_ci}
455e41f4b71Sopenharmony_ci
456e41f4b71Sopenharmony_ci```
457e41f4b71Sopenharmony_ci
458e41f4b71Sopenharmony_ciExample:
459e41f4b71Sopenharmony_ci
460e41f4b71Sopenharmony_ciUse of a relative layout reduces both the nesting depth and quantity of components, shortening the time required for layout to 123 ms 278 us.
461e41f4b71Sopenharmony_ci
462e41f4b71Sopenharmony_ci```ts
463e41f4b71Sopenharmony_ci
464e41f4b71Sopenharmony_ci@Entry
465e41f4b71Sopenharmony_ci@Component
466e41f4b71Sopenharmony_cistruct RelativePerformance {
467e41f4b71Sopenharmony_ci  @State message: string = 'Hello World'
468e41f4b71Sopenharmony_ci
469e41f4b71Sopenharmony_ci  build() {
470e41f4b71Sopenharmony_ci    RelativeContainer(){
471e41f4b71Sopenharmony_ci      Image($r("app.media.app_icon"))
472e41f4b71Sopenharmony_ci        .height(300)
473e41f4b71Sopenharmony_ci        .width("100%")
474e41f4b71Sopenharmony_ci        .id("topImage")
475e41f4b71Sopenharmony_ci        .alignRules({
476e41f4b71Sopenharmony_ci          left: { anchor: "__container__", align: HorizontalAlign.Start },
477e41f4b71Sopenharmony_ci          top: {anchor: "__container__", align: VerticalAlign.Top }
478e41f4b71Sopenharmony_ci        })
479e41f4b71Sopenharmony_ci      Image($r("app.media.app_icon"))
480e41f4b71Sopenharmony_ci        .width(40)
481e41f4b71Sopenharmony_ci        .aspectRatio(1)
482e41f4b71Sopenharmony_ci        .margin(4)
483e41f4b71Sopenharmony_ci        .id("topCornerImage")
484e41f4b71Sopenharmony_ci        .alignRules({
485e41f4b71Sopenharmony_ci          right: { anchor: "__container__", align: HorizontalAlign.End },
486e41f4b71Sopenharmony_ci          center: {anchor: "topImage", align: VerticalAlign.Bottom }
487e41f4b71Sopenharmony_ci        })
488e41f4b71Sopenharmony_ci      Text("Name")
489e41f4b71Sopenharmony_ci        .id("name")
490e41f4b71Sopenharmony_ci        .margin(4)
491e41f4b71Sopenharmony_ci        .alignRules({
492e41f4b71Sopenharmony_ci          left: { anchor: "topCornerImage", align: HorizontalAlign.Start },
493e41f4b71Sopenharmony_ci          top: {anchor: "topCornerImage", align: VerticalAlign.Bottom }
494e41f4b71Sopenharmony_ci        })
495e41f4b71Sopenharmony_ci      Text("Singapore")
496e41f4b71Sopenharmony_ci        .margin(8)
497e41f4b71Sopenharmony_ci        .fontWeight(FontWeight.Bolder)
498e41f4b71Sopenharmony_ci        .fontSize(20)
499e41f4b71Sopenharmony_ci        .id("singapore")
500e41f4b71Sopenharmony_ci        .alignRules({
501e41f4b71Sopenharmony_ci          left: { anchor: "__container__", align: HorizontalAlign.Start },
502e41f4b71Sopenharmony_ci          top: {anchor: "name", align: VerticalAlign.Bottom }
503e41f4b71Sopenharmony_ci        })
504e41f4b71Sopenharmony_ci      Text("Camera")
505e41f4b71Sopenharmony_ci        .margin(8)
506e41f4b71Sopenharmony_ci        .id("camera")
507e41f4b71Sopenharmony_ci        .alignRules({
508e41f4b71Sopenharmony_ci          left: { anchor: "__container__", align: HorizontalAlign.Start },
509e41f4b71Sopenharmony_ci          top: {anchor: "singapore", align: VerticalAlign.Bottom }
510e41f4b71Sopenharmony_ci        })
511e41f4b71Sopenharmony_ci      TextInput()
512e41f4b71Sopenharmony_ci        .id("cameraInput")
513e41f4b71Sopenharmony_ci        .alignRules({
514e41f4b71Sopenharmony_ci          left: { anchor: "camera", align: HorizontalAlign.End },
515e41f4b71Sopenharmony_ci          right:{ anchor: "__container__", align: HorizontalAlign.End },
516e41f4b71Sopenharmony_ci          top: {anchor: "camera", align: VerticalAlign.Top },
517e41f4b71Sopenharmony_ci          bottom: { anchor: "camera", align: VerticalAlign.Bottom }
518e41f4b71Sopenharmony_ci        })
519e41f4b71Sopenharmony_ci      Text("Settings")
520e41f4b71Sopenharmony_ci        .margin(8)
521e41f4b71Sopenharmony_ci        .id("settings")
522e41f4b71Sopenharmony_ci        .alignRules({
523e41f4b71Sopenharmony_ci          left: { anchor: "__container__", align: HorizontalAlign.Start },
524e41f4b71Sopenharmony_ci          top: {anchor: "camera", align: VerticalAlign.Bottom }
525e41f4b71Sopenharmony_ci        })
526e41f4b71Sopenharmony_ci      TextInput()
527e41f4b71Sopenharmony_ci        .id("settingInput")
528e41f4b71Sopenharmony_ci        .alignRules({
529e41f4b71Sopenharmony_ci          left: { anchor: "settings", align: HorizontalAlign.End },
530e41f4b71Sopenharmony_ci          right:{ anchor: "__container__", align: HorizontalAlign.End },
531e41f4b71Sopenharmony_ci          top: {anchor: "settings", align: VerticalAlign.Top },
532e41f4b71Sopenharmony_ci          bottom: { anchor: "settings", align: VerticalAlign.Bottom }
533e41f4b71Sopenharmony_ci        })
534e41f4b71Sopenharmony_ci      Image($r("app.media.app_icon"))
535e41f4b71Sopenharmony_ci        .id("descriptionIcon")
536e41f4b71Sopenharmony_ci        .margin(8)
537e41f4b71Sopenharmony_ci        .width(80)
538e41f4b71Sopenharmony_ci        .aspectRatio(1)
539e41f4b71Sopenharmony_ci        .alignRules({
540e41f4b71Sopenharmony_ci          left: { anchor: "__container__", align: HorizontalAlign.Start },
541e41f4b71Sopenharmony_ci          top: {anchor: "settings", align: VerticalAlign.Bottom }
542e41f4b71Sopenharmony_ci        })
543e41f4b71Sopenharmony_ci      Text("Description")
544e41f4b71Sopenharmony_ci        .id("description")
545e41f4b71Sopenharmony_ci        .margin(8)
546e41f4b71Sopenharmony_ci        .alignRules({
547e41f4b71Sopenharmony_ci          left: { anchor: "__container__", align: HorizontalAlign.Start },
548e41f4b71Sopenharmony_ci          top: {anchor: "descriptionIcon", align: VerticalAlign.Bottom }
549e41f4b71Sopenharmony_ci        })
550e41f4b71Sopenharmony_ci      Text("Title")
551e41f4b71Sopenharmony_ci        .fontWeight(FontWeight.Bold)
552e41f4b71Sopenharmony_ci        .id("title")
553e41f4b71Sopenharmony_ci        .margin(8)
554e41f4b71Sopenharmony_ci        .alignRules({
555e41f4b71Sopenharmony_ci          left: { anchor: "description", align: HorizontalAlign.End },
556e41f4b71Sopenharmony_ci          top: {anchor: "descriptionIcon", align: VerticalAlign.Top }
557e41f4b71Sopenharmony_ci        })
558e41f4b71Sopenharmony_ci      Text("Long Text")
559e41f4b71Sopenharmony_ci        .id("longText")
560e41f4b71Sopenharmony_ci        .margin(8)
561e41f4b71Sopenharmony_ci        .alignRules({
562e41f4b71Sopenharmony_ci          left: { anchor: "description", align: HorizontalAlign.End },
563e41f4b71Sopenharmony_ci          right: { anchor: "__container__", align: HorizontalAlign.End },
564e41f4b71Sopenharmony_ci          top: {anchor: "title", align: VerticalAlign.Bottom }
565e41f4b71Sopenharmony_ci        })
566e41f4b71Sopenharmony_ci      Button("Discard")
567e41f4b71Sopenharmony_ci        .id("discard")
568e41f4b71Sopenharmony_ci        .margin(8)
569e41f4b71Sopenharmony_ci        .alignRules({
570e41f4b71Sopenharmony_ci          right: { anchor: "__container__", align: HorizontalAlign.End },
571e41f4b71Sopenharmony_ci          bottom: {anchor: "__container__", align: VerticalAlign.Bottom }
572e41f4b71Sopenharmony_ci        })
573e41f4b71Sopenharmony_ci      Button("Upload")
574e41f4b71Sopenharmony_ci        .id("upload")
575e41f4b71Sopenharmony_ci        .margin(8)
576e41f4b71Sopenharmony_ci        .alignRules({
577e41f4b71Sopenharmony_ci          right: { anchor: "discard", align: HorizontalAlign.Start },
578e41f4b71Sopenharmony_ci          bottom: {anchor: "__container__", align: VerticalAlign.Bottom }
579e41f4b71Sopenharmony_ci        })
580e41f4b71Sopenharmony_ci    }.width("100%").height("100%")
581e41f4b71Sopenharmony_ci  }
582e41f4b71Sopenharmony_ci}
583e41f4b71Sopenharmony_ci
584e41f4b71Sopenharmony_ci```
585e41f4b71Sopenharmony_ci
586e41f4b71Sopenharmony_ci
587e41f4b71Sopenharmony_ci## Using Layout Optimization Tools
588e41f4b71Sopenharmony_ci
589e41f4b71Sopenharmony_ci[DevEco Studio](../quick-start/deveco-studio-user-guide-for-openharmony.md) has a built-in ArkUI Inspector tool, which you can use to inspect the UI display effect of your application running on a real device. With ArkUI Inspector, you can quickly identify layout and other UI-related issues, as well as inspect the layout relationships and attributes of components.
590