1e41f4b71Sopenharmony_ci# Reducing Redundant Operations on First Frame Drawing
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci------
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ci## Application Cold Start and Home Page Loading and Drawing
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciA code start is a startup mode where an application is started from scratch – the background does not have a process of the application, and therefore the system creates a new process and allocates it to the application.
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ciThe cold start process can be divided into four phases: application process creation and initialization, application and ability initialization, ability lifecycle, and home page loading and drawing, as shown below.
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci![](figures/ColdStart.png)
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ciHome page loading and drawing is not only one of the four phases of application cold start, but also the most important phase of first frame drawing. It can be further divided into three phases: page load, measurement and layout, and render. This topic explores how application performance can be improved at these phases.
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ci![](figures/Render-FirstFrame.png)
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ci## Reducing Page Load Time
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ciYou can reduce your page load time by loading pages on demand or reducing the lifecycle time of custom components.
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ci#### On-demand Loading
22e41f4b71Sopenharmony_ci
23e41f4b71Sopenharmony_ciOn-demand loading, as its name implies, loads resources only when they are needed. It avoids initializing and loading all elements at a time. In this way, the time required for creating list elements is reduced, allowing pages to load faster.
24e41f4b71Sopenharmony_ci
25e41f4b71Sopenharmony_ci**Negative example**: There is a list with 10,000 elements (the sheer number is intended to make it easier to observe the benefits of on-demand loading). If each of the list element is initialized and loaded during page load, the page load time will be excessively long.
26e41f4b71Sopenharmony_ci
27e41f4b71Sopenharmony_ci```ts
28e41f4b71Sopenharmony_ci@Entry
29e41f4b71Sopenharmony_ci@Component
30e41f4b71Sopenharmony_cistruct AllLoad {
31e41f4b71Sopenharmony_ci  @State arr: String[] = Array.from(Array<string>(10000), (val,i) =>i.toString());
32e41f4b71Sopenharmony_ci  build() {
33e41f4b71Sopenharmony_ci    List() {
34e41f4b71Sopenharmony_ci      ForEach(this.arr, (item: string) => {
35e41f4b71Sopenharmony_ci        ListItem() {
36e41f4b71Sopenharmony_ci          Text(`item value: ${item}`)
37e41f4b71Sopenharmony_ci            .fontSize(20)
38e41f4b71Sopenharmony_ci            .margin({ left: 10 })
39e41f4b71Sopenharmony_ci        }
40e41f4b71Sopenharmony_ci      }, (item: string) => item.toString())
41e41f4b71Sopenharmony_ci    }
42e41f4b71Sopenharmony_ci  }
43e41f4b71Sopenharmony_ci}
44e41f4b71Sopenharmony_ci```
45e41f4b71Sopenharmony_ci
46e41f4b71Sopenharmony_ci**Optimization**: Replace **ForEach** with **LazyForEach** to avoid initializing and loading all elements at a time.
47e41f4b71Sopenharmony_ci
48e41f4b71Sopenharmony_ci```ts
49e41f4b71Sopenharmony_ciclass BasicDataSource implements IDataSource {
50e41f4b71Sopenharmony_ci  private listeners: DataChangeListener[] = [];
51e41f4b71Sopenharmony_ci  private originDataArray: string[] = [];
52e41f4b71Sopenharmony_ci
53e41f4b71Sopenharmony_ci  public totalCount(): number {
54e41f4b71Sopenharmony_ci    return 0;
55e41f4b71Sopenharmony_ci  }
56e41f4b71Sopenharmony_ci
57e41f4b71Sopenharmony_ci  public getData(index: number): string {
58e41f4b71Sopenharmony_ci    return this.originDataArray[index]
59e41f4b71Sopenharmony_ci  }
60e41f4b71Sopenharmony_ci
61e41f4b71Sopenharmony_ci  // Register a listener for data changes.
62e41f4b71Sopenharmony_ci  registerDataChangeListener(listener: DataChangeListener): void {
63e41f4b71Sopenharmony_ci    if (this.listeners.indexOf(listener) < 0) {
64e41f4b71Sopenharmony_ci      console.info('add listener')
65e41f4b71Sopenharmony_ci      this.listeners.push(listener)
66e41f4b71Sopenharmony_ci    }
67e41f4b71Sopenharmony_ci  }
68e41f4b71Sopenharmony_ci
69e41f4b71Sopenharmony_ci  // Deregister the listener for data changes.
70e41f4b71Sopenharmony_ci  unregisterDataChangeListener(listener: DataChangeListener): void {
71e41f4b71Sopenharmony_ci    const pos = this.listeners.indexOf(listener);
72e41f4b71Sopenharmony_ci    if (pos >= 0) {
73e41f4b71Sopenharmony_ci      console.info('remove listener')
74e41f4b71Sopenharmony_ci      this.listeners.splice(pos, 1)
75e41f4b71Sopenharmony_ci    }
76e41f4b71Sopenharmony_ci  }
77e41f4b71Sopenharmony_ci
78e41f4b71Sopenharmony_ci  // Invoked when all data is reloaded.
79e41f4b71Sopenharmony_ci  notifyDataReload(): void {
80e41f4b71Sopenharmony_ci    this.listeners.forEach(listener => {
81e41f4b71Sopenharmony_ci      listener.onDataReloaded()
82e41f4b71Sopenharmony_ci    })
83e41f4b71Sopenharmony_ci  }
84e41f4b71Sopenharmony_ci
85e41f4b71Sopenharmony_ci  // Invoked when data is added to the position indicated by the specified index.
86e41f4b71Sopenharmony_ci  notifyDataAdd(index: number): void {
87e41f4b71Sopenharmony_ci    this.listeners.forEach(listener => {
88e41f4b71Sopenharmony_ci      listener.onDataAdd(index)
89e41f4b71Sopenharmony_ci    })
90e41f4b71Sopenharmony_ci  }
91e41f4b71Sopenharmony_ci
92e41f4b71Sopenharmony_ci  // Invoked when data in the position indicated by the specified index is changed.
93e41f4b71Sopenharmony_ci  notifyDataChange(index: number): void {
94e41f4b71Sopenharmony_ci    this.listeners.forEach(listener => {
95e41f4b71Sopenharmony_ci      listener.onDataChange(index)
96e41f4b71Sopenharmony_ci    })
97e41f4b71Sopenharmony_ci  }
98e41f4b71Sopenharmony_ci
99e41f4b71Sopenharmony_ci  // Invoked when data is deleted from the position indicated by the specified index. LazyForEach will update the displayed content accordingly.
100e41f4b71Sopenharmony_ci  notifyDataDelete(index: number): void {
101e41f4b71Sopenharmony_ci    this.listeners.forEach(listener => {
102e41f4b71Sopenharmony_ci      listener.onDataDelete(index)
103e41f4b71Sopenharmony_ci    })
104e41f4b71Sopenharmony_ci  }
105e41f4b71Sopenharmony_ci
106e41f4b71Sopenharmony_ci  // Invoked when data is moved.
107e41f4b71Sopenharmony_ci  notifyDataMove(from: number, to: number): void {
108e41f4b71Sopenharmony_ci    this.listeners.forEach(listener => {
109e41f4b71Sopenharmony_ci      listener.onDataMove(from, to)
110e41f4b71Sopenharmony_ci    })
111e41f4b71Sopenharmony_ci  }
112e41f4b71Sopenharmony_ci}
113e41f4b71Sopenharmony_ci
114e41f4b71Sopenharmony_ciclass MyDataSource extends BasicDataSource {
115e41f4b71Sopenharmony_ci  private dataArray: string[] = Array.from(Array<string>(10000), (val, i) => i.toString());
116e41f4b71Sopenharmony_ci
117e41f4b71Sopenharmony_ci  public totalCount(): number {
118e41f4b71Sopenharmony_ci    return this.dataArray.length
119e41f4b71Sopenharmony_ci  }
120e41f4b71Sopenharmony_ci
121e41f4b71Sopenharmony_ci  public getData(index: number): string {
122e41f4b71Sopenharmony_ci    return this.dataArray[index]
123e41f4b71Sopenharmony_ci  }
124e41f4b71Sopenharmony_ci
125e41f4b71Sopenharmony_ci  public addData(index: number, data: string): void {
126e41f4b71Sopenharmony_ci    this.dataArray.splice(index, 0, data)
127e41f4b71Sopenharmony_ci    this.notifyDataAdd(index)
128e41f4b71Sopenharmony_ci  }
129e41f4b71Sopenharmony_ci
130e41f4b71Sopenharmony_ci  public pushData(data: string): void {
131e41f4b71Sopenharmony_ci    this.dataArray.push(data)
132e41f4b71Sopenharmony_ci    this.notifyDataAdd(this.dataArray.length - 1)
133e41f4b71Sopenharmony_ci  }
134e41f4b71Sopenharmony_ci}
135e41f4b71Sopenharmony_ci
136e41f4b71Sopenharmony_ci@Entry
137e41f4b71Sopenharmony_ci@Component
138e41f4b71Sopenharmony_cistruct SmartLoad {
139e41f4b71Sopenharmony_ci  private data: MyDataSource = new MyDataSource()
140e41f4b71Sopenharmony_ci
141e41f4b71Sopenharmony_ci  build() {
142e41f4b71Sopenharmony_ci    List() {
143e41f4b71Sopenharmony_ci      LazyForEach(this.data, (item: string) => {
144e41f4b71Sopenharmony_ci        ListItem() {
145e41f4b71Sopenharmony_ci          Text(`item value: ${item}`)
146e41f4b71Sopenharmony_ci            .fontSize(20)
147e41f4b71Sopenharmony_ci            .margin({ left: 10 })
148e41f4b71Sopenharmony_ci        }
149e41f4b71Sopenharmony_ci      }, (item:string) => item)
150e41f4b71Sopenharmony_ci    }
151e41f4b71Sopenharmony_ci  }
152e41f4b71Sopenharmony_ci}
153e41f4b71Sopenharmony_ci```
154e41f4b71Sopenharmony_ci
155e41f4b71Sopenharmony_ci
156e41f4b71Sopenharmony_ci
157e41f4b71Sopenharmony_ci#### Reducing Lifecycle of Custom Components
158e41f4b71Sopenharmony_ci
159e41f4b71Sopenharmony_ciThe custom component lifecycle **aboutToAppear** is time-consuming and, if not well managed, may greatly increase page load times and even block subsequent layout rendering of the main thread. Therefore, the lifecycle needs to be converted to a worker thread task so that the page can be rendered without waiting for the lifecycle to be completed first and the main thread will not be blocked at the startWindowIcon page.
160e41f4b71Sopenharmony_ci
161e41f4b71Sopenharmony_ci**Negative example**: The time-consuming lifecycle of a custom component blocks the layout rendering of the main thread.
162e41f4b71Sopenharmony_ci
163e41f4b71Sopenharmony_ci```ts
164e41f4b71Sopenharmony_ci@Entry
165e41f4b71Sopenharmony_ci@Component
166e41f4b71Sopenharmony_cistruct TaskSync {
167e41f4b71Sopenharmony_ci  @State private text: string = "";
168e41f4b71Sopenharmony_ci  private count: number = 0;
169e41f4b71Sopenharmony_ci
170e41f4b71Sopenharmony_ci  aboutToAppear() {
171e41f4b71Sopenharmony_ci    this.text = 'hello world';
172e41f4b71Sopenharmony_ci    this.computeTask(); // Synchronization task
173e41f4b71Sopenharmony_ci  }
174e41f4b71Sopenharmony_ci
175e41f4b71Sopenharmony_ci  build() {
176e41f4b71Sopenharmony_ci    Column({space: 10}) {
177e41f4b71Sopenharmony_ci      Text(this.text).fontSize(50)
178e41f4b71Sopenharmony_ci    }
179e41f4b71Sopenharmony_ci    .width('100%')
180e41f4b71Sopenharmony_ci    .height('100%')
181e41f4b71Sopenharmony_ci    .padding(10)
182e41f4b71Sopenharmony_ci  }
183e41f4b71Sopenharmony_ci
184e41f4b71Sopenharmony_ci  computeTask() {
185e41f4b71Sopenharmony_ci    this.count = 0;
186e41f4b71Sopenharmony_ci    while (this.count < 100000000) {
187e41f4b71Sopenharmony_ci      this.count++;
188e41f4b71Sopenharmony_ci    }
189e41f4b71Sopenharmony_ci    this.text = 'task complete';
190e41f4b71Sopenharmony_ci  }
191e41f4b71Sopenharmony_ci}
192e41f4b71Sopenharmony_ci```
193e41f4b71Sopenharmony_ci
194e41f4b71Sopenharmony_ci**Optimization**: Convert the time-consuming lifecycle to a worker thread task. In this way, the page is drawn first, and then the worker thread result is sent to the main thread and updated to the page.
195e41f4b71Sopenharmony_ci
196e41f4b71Sopenharmony_ci```ts
197e41f4b71Sopenharmony_ci// TaskAsync.ets
198e41f4b71Sopenharmony_ciimport worker from '@ohos.worker';
199e41f4b71Sopenharmony_ci
200e41f4b71Sopenharmony_ci@Entry
201e41f4b71Sopenharmony_ci@Component
202e41f4b71Sopenharmony_cistruct TaskAsync {
203e41f4b71Sopenharmony_ci  @State private text: string = "";
204e41f4b71Sopenharmony_ci  private workerInstance:worker.ThreadWorker = new worker.ThreadWorker("entry/ets/workers/worker.ts");
205e41f4b71Sopenharmony_ci
206e41f4b71Sopenharmony_ci  aboutToAppear() {
207e41f4b71Sopenharmony_ci    // Process messages from the worker thread.
208e41f4b71Sopenharmony_ci    this.workerInstance.onmessage = (message)=> {
209e41f4b71Sopenharmony_ci      console.info('message from worker: ' + JSON.stringify(message))
210e41f4b71Sopenharmony_ci      this.text = JSON.parse(JSON.stringify(message)).data
211e41f4b71Sopenharmony_ci      this.workerInstance.terminate()
212e41f4b71Sopenharmony_ci    }
213e41f4b71Sopenharmony_ci    this.text = 'hello world';
214e41f4b71Sopenharmony_ci    // Execute the worker thread task.
215e41f4b71Sopenharmony_ci    this.computeTaskAsync();
216e41f4b71Sopenharmony_ci  }
217e41f4b71Sopenharmony_ci
218e41f4b71Sopenharmony_ci  build() {
219e41f4b71Sopenharmony_ci    Column({space: 10}) {
220e41f4b71Sopenharmony_ci      Text(this.text).fontSize(50)
221e41f4b71Sopenharmony_ci    }
222e41f4b71Sopenharmony_ci    .width('100%')
223e41f4b71Sopenharmony_ci    .height('100%')
224e41f4b71Sopenharmony_ci    .padding(10)
225e41f4b71Sopenharmony_ci  }
226e41f4b71Sopenharmony_ci  private async computeTaskAsync(){
227e41f4b71Sopenharmony_ci    // Send a message to the worker thread.
228e41f4b71Sopenharmony_ci    this.workerInstance.postMessage('hello world')
229e41f4b71Sopenharmony_ci  }
230e41f4b71Sopenharmony_ci}
231e41f4b71Sopenharmony_ci```
232e41f4b71Sopenharmony_ci
233e41f4b71Sopenharmony_ci```ts
234e41f4b71Sopenharmony_ci// worker.ts
235e41f4b71Sopenharmony_ciimport worker from '@ohos.worker';
236e41f4b71Sopenharmony_ci
237e41f4b71Sopenharmony_cilet parentPort = worker.workerPort;
238e41f4b71Sopenharmony_ci
239e41f4b71Sopenharmony_cifunction computeTask(count: number) {
240e41f4b71Sopenharmony_ci  while (count < 100000000) {
241e41f4b71Sopenharmony_ci    count++;
242e41f4b71Sopenharmony_ci  }
243e41f4b71Sopenharmony_ci  return 'task complete'
244e41f4b71Sopenharmony_ci}
245e41f4b71Sopenharmony_ci// Process messages from the main thread.
246e41f4b71Sopenharmony_ciparentPort.onmessage = (message) => {
247e41f4b71Sopenharmony_ci  console.info("onmessage: " + JSON.stringify(message));
248e41f4b71Sopenharmony_ci  // Send a message to the main thread.
249e41f4b71Sopenharmony_ci  parentPort.postMessage(computeTask(0));
250e41f4b71Sopenharmony_ci}
251e41f4b71Sopenharmony_ci```
252e41f4b71Sopenharmony_ci
253e41f4b71Sopenharmony_ci
254e41f4b71Sopenharmony_ci
255e41f4b71Sopenharmony_ci## Reducing Layout Time
256e41f4b71Sopenharmony_ci
257e41f4b71Sopenharmony_ciReducing layout time can be achieved by asynchronous loading and reduced nesting.
258e41f4b71Sopenharmony_ci
259e41f4b71Sopenharmony_ci#### Asynchronous Loading
260e41f4b71Sopenharmony_ci
261e41f4b71Sopenharmony_ciDuring synchronous loading, images are loaded in the main thread. This means that, page layout needs to wait until the main thread has completed the **makePixelMap** task, resulting in long page layout times. On the contrary, during asynchronous loading, images are loaded in other threads while page layout is executed in the main thread. In this way, no blocking occurs, leading to faster page layout and better performance. However, not all image loading must be asynchronous loading. For small local images that are fast to load, synchronous loading (with **syncLoad** set to **true**) is preferrable.
262e41f4b71Sopenharmony_ci
263e41f4b71Sopenharmony_ci**Negative example**: The **\<Image>** component is used to synchronously load high-resolution images, blocking the UI thread and increasing the total page layout time.
264e41f4b71Sopenharmony_ci
265e41f4b71Sopenharmony_ci```ts
266e41f4b71Sopenharmony_ci@Entry
267e41f4b71Sopenharmony_ci@Component
268e41f4b71Sopenharmony_cistruct SyncLoadImage {
269e41f4b71Sopenharmony_ci  @State arr: String[] = Array.from(Array<string>(100), (val,i) =>i.toString());
270e41f4b71Sopenharmony_ci  build() {
271e41f4b71Sopenharmony_ci    Column() {
272e41f4b71Sopenharmony_ci      Row() {
273e41f4b71Sopenharmony_ci        List() {
274e41f4b71Sopenharmony_ci          ForEach(this.arr, (item: string) => {
275e41f4b71Sopenharmony_ci            ListItem() {
276e41f4b71Sopenharmony_ci              Image($r('app.media.4k'))
277e41f4b71Sopenharmony_ci                .border({ width: 1 })
278e41f4b71Sopenharmony_ci                .borderStyle(BorderStyle.Dashed)
279e41f4b71Sopenharmony_ci                .height(100)
280e41f4b71Sopenharmony_ci                .width(100)
281e41f4b71Sopenharmony_ci                .syncLoad(true)
282e41f4b71Sopenharmony_ci            }
283e41f4b71Sopenharmony_ci          }, (item: string) => item.toString())
284e41f4b71Sopenharmony_ci        }
285e41f4b71Sopenharmony_ci      }
286e41f4b71Sopenharmony_ci    }
287e41f4b71Sopenharmony_ci  }
288e41f4b71Sopenharmony_ci}
289e41f4b71Sopenharmony_ci```
290e41f4b71Sopenharmony_ci
291e41f4b71Sopenharmony_ci**Optimization**: The **\<Image>** component is loaded in the default asynchronous loading mode, which avoids blocking the UI thread and reduces the page layout time.
292e41f4b71Sopenharmony_ci
293e41f4b71Sopenharmony_ci```ts
294e41f4b71Sopenharmony_ci@Entry
295e41f4b71Sopenharmony_ci@Component
296e41f4b71Sopenharmony_cistruct AsyncLoadImage {
297e41f4b71Sopenharmony_ci  @State arr: String[] = Array.from(Array<string>(100), (val,i) =>i.toString());
298e41f4b71Sopenharmony_ci    build() {
299e41f4b71Sopenharmony_ci      Column() {
300e41f4b71Sopenharmony_ci        Row() {
301e41f4b71Sopenharmony_ci          List() {
302e41f4b71Sopenharmony_ci            ForEach(this.arr, (item: string) => {
303e41f4b71Sopenharmony_ci              ListItem() {
304e41f4b71Sopenharmony_ci                Image($r('app.media.4k'))
305e41f4b71Sopenharmony_ci                  .border({ width: 1 })
306e41f4b71Sopenharmony_ci                  .borderStyle(BorderStyle.Dashed)
307e41f4b71Sopenharmony_ci                  .height(100)
308e41f4b71Sopenharmony_ci                  .width(100)
309e41f4b71Sopenharmony_ci              }
310e41f4b71Sopenharmony_ci            }, (item: string) => item.toString())
311e41f4b71Sopenharmony_ci          }
312e41f4b71Sopenharmony_ci        }
313e41f4b71Sopenharmony_ci      }
314e41f4b71Sopenharmony_ci  }
315e41f4b71Sopenharmony_ci}
316e41f4b71Sopenharmony_ci```
317e41f4b71Sopenharmony_ci
318e41f4b71Sopenharmony_ci
319e41f4b71Sopenharmony_ci
320e41f4b71Sopenharmony_ci#### Reducing Nesting
321e41f4b71Sopenharmony_ci
322e41f4b71Sopenharmony_ciThe view hierarchy can significantly affect application performance. Flatter view hierarchies can bring faster page layout and better layout performance. Therefore, whenever possible, reduce nesting and eliminate misplaced container components.
323e41f4b71Sopenharmony_ci
324e41f4b71Sopenharmony_ci**Negative example**: A **\<Grid>** container is used to load 1000 grids at a time, and additional three-layer **\<Flex>** containers are used , resulting in an unnecessarily deeply nested structure.
325e41f4b71Sopenharmony_ci
326e41f4b71Sopenharmony_ci```ts
327e41f4b71Sopenharmony_ci@Entry
328e41f4b71Sopenharmony_ci@Component
329e41f4b71Sopenharmony_cistruct Depth1 {
330e41f4b71Sopenharmony_ci  @State number: Number[] = Array.from(Array<number>(1000), (val, i) => i);
331e41f4b71Sopenharmony_ci  scroller: Scroller = new Scroller()
332e41f4b71Sopenharmony_ci
333e41f4b71Sopenharmony_ci  build() {
334e41f4b71Sopenharmony_ci    Column() {
335e41f4b71Sopenharmony_ci      Grid(this.scroller) {
336e41f4b71Sopenharmony_ci        ForEach(this.number, (item: number) => {
337e41f4b71Sopenharmony_ci          GridItem() {
338e41f4b71Sopenharmony_ci            Flex() {
339e41f4b71Sopenharmony_ci              Flex() {
340e41f4b71Sopenharmony_ci                Flex() {
341e41f4b71Sopenharmony_ci                  Text(item.toString())
342e41f4b71Sopenharmony_ci                    .fontSize(16)
343e41f4b71Sopenharmony_ci                    .backgroundColor(0xF9CF93)
344e41f4b71Sopenharmony_ci                    .width('100%')
345e41f4b71Sopenharmony_ci                    .height(80)
346e41f4b71Sopenharmony_ci                    .textAlign(TextAlign.Center)
347e41f4b71Sopenharmony_ci                    .border({width:1})
348e41f4b71Sopenharmony_ci                }
349e41f4b71Sopenharmony_ci              }
350e41f4b71Sopenharmony_ci            }
351e41f4b71Sopenharmony_ci          }
352e41f4b71Sopenharmony_ci        }, (item:string) => item)
353e41f4b71Sopenharmony_ci      }
354e41f4b71Sopenharmony_ci      .columnsTemplate('1fr 1fr 1fr 1fr 1fr')
355e41f4b71Sopenharmony_ci      .columnsGap(0)
356e41f4b71Sopenharmony_ci      .rowsGap(0)
357e41f4b71Sopenharmony_ci      .size({ width: "100%", height: "100%" })
358e41f4b71Sopenharmony_ci    }
359e41f4b71Sopenharmony_ci  }
360e41f4b71Sopenharmony_ci}
361e41f4b71Sopenharmony_ci```
362e41f4b71Sopenharmony_ci
363e41f4b71Sopenharmony_ci**Optimization**: A **\<Grid>** container is used to load 1000 grids at a time, but this time no unnecessary containers are used, which leads to faster layout.
364e41f4b71Sopenharmony_ci
365e41f4b71Sopenharmony_ci```ts
366e41f4b71Sopenharmony_ci@Entry
367e41f4b71Sopenharmony_ci@Component
368e41f4b71Sopenharmony_cistruct Depth2 {
369e41f4b71Sopenharmony_ci  @State number: Number[] = Array.from(Array<number>(1000), (val, i) => i);
370e41f4b71Sopenharmony_ci  scroller: Scroller = new Scroller()
371e41f4b71Sopenharmony_ci
372e41f4b71Sopenharmony_ci  build() {
373e41f4b71Sopenharmony_ci    Column() {
374e41f4b71Sopenharmony_ci      Grid(this.scroller) {
375e41f4b71Sopenharmony_ci        ForEach(this.number, (item: number) => {
376e41f4b71Sopenharmony_ci          GridItem() {
377e41f4b71Sopenharmony_ci                  Text(item.toString())
378e41f4b71Sopenharmony_ci                    .fontSize(16)
379e41f4b71Sopenharmony_ci                    .backgroundColor(0xF9CF93)
380e41f4b71Sopenharmony_ci                    .width('100%')
381e41f4b71Sopenharmony_ci                    .height(80)
382e41f4b71Sopenharmony_ci                    .textAlign(TextAlign.Center)
383e41f4b71Sopenharmony_ci                    .border({width:1})
384e41f4b71Sopenharmony_ci          }
385e41f4b71Sopenharmony_ci        }, (item:string) => item)
386e41f4b71Sopenharmony_ci      }
387e41f4b71Sopenharmony_ci      .columnsTemplate('1fr 1fr 1fr 1fr 1fr')
388e41f4b71Sopenharmony_ci      .columnsGap(0)
389e41f4b71Sopenharmony_ci      .rowsGap(0)
390e41f4b71Sopenharmony_ci      .size({ width: "100%", height: "100%" })
391e41f4b71Sopenharmony_ci    }
392e41f4b71Sopenharmony_ci  }
393e41f4b71Sopenharmony_ci}
394e41f4b71Sopenharmony_ci```
395e41f4b71Sopenharmony_ci
396e41f4b71Sopenharmony_ci
397e41f4b71Sopenharmony_ci
398e41f4b71Sopenharmony_ci## Reducing Render Time
399e41f4b71Sopenharmony_ci
400e41f4b71Sopenharmony_ciYou can reduce render time by replacing visibility control with conditional rendering.
401e41f4b71Sopenharmony_ci
402e41f4b71Sopenharmony_ci#### Conditional Rendering
403e41f4b71Sopenharmony_ci
404e41f4b71Sopenharmony_ciReplacing visibility control with conditional rendering can significantly reduce the render time during first frame drawing. With visibility control, even if a component is hidden, it still needs to be re-created when the page is re-rendered. Therefore, in scenarios where performance is critical, you are advised to use conditional rendering instead.
405e41f4b71Sopenharmony_ci
406e41f4b71Sopenharmony_ci**Negative example**: The **visibility** attribute is used to display or hide the component.
407e41f4b71Sopenharmony_ci
408e41f4b71Sopenharmony_ci```ts
409e41f4b71Sopenharmony_ci@Entry
410e41f4b71Sopenharmony_ci@Component
411e41f4b71Sopenharmony_cistruct VisibilityExample {
412e41f4b71Sopenharmony_ci  build() {
413e41f4b71Sopenharmony_ci    Column() {
414e41f4b71Sopenharmony_ci      Column() {
415e41f4b71Sopenharmony_ci        // The component is hidden and does not take up space in the layout.
416e41f4b71Sopenharmony_ci        Text('None').fontSize(9).width('90%').fontColor(0xCCCCCC)
417e41f4b71Sopenharmony_ci        Row().visibility(Visibility.None).width('90%').height(80).backgroundColor(0xAFEEEE)
418e41f4b71Sopenharmony_ci
419e41f4b71Sopenharmony_ci        // The component is hidden but takes up space in the layout.
420e41f4b71Sopenharmony_ci        Text('Hidden').fontSize(9).width('90%').fontColor(0xCCCCCC)
421e41f4b71Sopenharmony_ci        Row().visibility(Visibility.Hidden).width('90%').height(80).backgroundColor(0xAFEEEE)
422e41f4b71Sopenharmony_ci
423e41f4b71Sopenharmony_ci        // The component is visible, which is the default display mode.
424e41f4b71Sopenharmony_ci        Text('Visible').fontSize(9).width('90%').fontColor(0xCCCCCC)
425e41f4b71Sopenharmony_ci        Row().visibility(Visibility.Visible).width('90%').height(80).backgroundColor(0xAFEEEE)
426e41f4b71Sopenharmony_ci      }.width('90%').border({ width: 1 })
427e41f4b71Sopenharmony_ci    }.width('100%').margin({ top: 5 })
428e41f4b71Sopenharmony_ci  }
429e41f4b71Sopenharmony_ci}
430e41f4b71Sopenharmony_ci```
431e41f4b71Sopenharmony_ci
432e41f4b71Sopenharmony_ci**Optimization**: Conditional rendering is used to replace visibility control.
433e41f4b71Sopenharmony_ci
434e41f4b71Sopenharmony_ci```ts
435e41f4b71Sopenharmony_ci@Entry
436e41f4b71Sopenharmony_ci@Component
437e41f4b71Sopenharmony_cistruct IsVisibleExample {
438e41f4b71Sopenharmony_ci  @State isVisible : boolean = true;
439e41f4b71Sopenharmony_ci
440e41f4b71Sopenharmony_ci  build() {
441e41f4b71Sopenharmony_ci    Column(){
442e41f4b71Sopenharmony_ci      Column() {
443e41f4b71Sopenharmony_ci        // The component is not rendered. In this way, it is hidden and does not take up space in the layout.
444e41f4b71Sopenharmony_ci        Text('None').fontSize(9).width('90%').fontColor(0xCCCCCC)
445e41f4b71Sopenharmony_ci        if (!this.isVisible) {
446e41f4b71Sopenharmony_ci          Row().width('90%').height(80).backgroundColor(0xAFEEEE)
447e41f4b71Sopenharmony_ci        }
448e41f4b71Sopenharmony_ci        
449e41f4b71Sopenharmony_ci        // Conditional rendering cannot be used to hide the component with it still taking up space in the layout.
450e41f4b71Sopenharmony_ci        
451e41f4b71Sopenharmony_ci        // The component is rendered. In this way, it becomes visible.
452e41f4b71Sopenharmony_ci        Text('Visible').fontSize(9).width('90%').fontColor(0xCCCCCC)
453e41f4b71Sopenharmony_ci        if (this.isVisible){
454e41f4b71Sopenharmony_ci          Row().width('90%').height(80).backgroundColor(0xAFEEEE)
455e41f4b71Sopenharmony_ci        }
456e41f4b71Sopenharmony_ci      }.width('90%').border({ width: 1 })
457e41f4b71Sopenharmony_ci    }.width('100%').margin({ top: 5 })
458e41f4b71Sopenharmony_ci  }
459e41f4b71Sopenharmony_ci}
460e41f4b71Sopenharmony_ci```
461