1e41f4b71Sopenharmony_ci# Using SmartPerf-Host to Analyze Application Performance
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci## Overview
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ciSmartperf-Host is an intuitive performance and power optimization tool that offers in-depth data mining and fine-grained data visualization. In this tool, you can gain visibility into a multitude of metrics in terms of CPU scheduling, frequency, process and thread time slices, heap memory, frame rate, and more, in swimlanes. Better yet, you can analyze the collected data intuitively on the GUI. This tool provides five analysis templates: frame rate analysis, CPU/thread scheduling analysis, application startup analysis, task pool analysis, and animation analysis. For details about how to use the tool, see [Smartperf-Host User Guide](../../device-dev/device-test/smartperf-host.md).
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciThis document provides some performance analysis examples to describe how to use the frame rate analysis and application startup analysis templates to collect and analyze performance data and identify areas of improvement.
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ci## Deployment
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ciBefore using SmartPerf-Host, deploy it on your local device. Then you can access SmartPerf-Host at **https://[*Device IP address*]:9000/application/**, as shown in the following figure.
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ci**Figure 1** Local deployment access page
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ci![](./figures/smartperf-host-using-1.png)
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ci## Performance Analysis
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ci### FrameTimeline: Frame Rate Analysis
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ciThe FrameTimeline feature allows you to record the rendering data of each frame, automatically identify frame freezing, and gain system trace information in the same period.
22e41f4b71Sopenharmony_ci
23e41f4b71Sopenharmony_ci#### Example
24e41f4b71Sopenharmony_ci
25e41f4b71Sopenharmony_ciIn this example, the **\<Grid>** component is used to implement a grid layout. Frame freezing or frame loss occurs during swiping on the application page. Let's see how the FrameTimeline feature works in this case.
26e41f4b71Sopenharmony_ci
27e41f4b71Sopenharmony_ci```
28e41f4b71Sopenharmony_ci@Entry  
29e41f4b71Sopenharmony_ci@Component  
30e41f4b71Sopenharmony_cistruct Index {  
31e41f4b71Sopenharmony_ci  @State children: number[] = Array.from<undefined, number>(Array(2000).fill(undefined), (_v: undefined, k) => k);  
32e41f4b71Sopenharmony_ci  build() {  
33e41f4b71Sopenharmony_ci    Scroll() {  
34e41f4b71Sopenharmony_ci      Grid() {  
35e41f4b71Sopenharmony_ci       ForEach(this.children, (item: number) => {  
36e41f4b71Sopenharmony_ci          GridItem() {  
37e41f4b71Sopenharmony_ci            Stack() {  
38e41f4b71Sopenharmony_ci              Stack() {  
39e41f4b71Sopenharmony_ci                Stack() {  
40e41f4b71Sopenharmony_ci                  Text(item.toString())  
41e41f4b71Sopenharmony_ci                    .fontSize(32)  
42e41f4b71Sopenharmony_ci                }  
43e41f4b71Sopenharmony_ci              }  
44e41f4b71Sopenharmony_ci            }  
45e41f4b71Sopenharmony_ci          }  
46e41f4b71Sopenharmony_ci        }, (item: number) => item.toString())  
47e41f4b71Sopenharmony_ci      }  
48e41f4b71Sopenharmony_ci      .columnsTemplate('1fr 1fr 1fr 1fr')  
49e41f4b71Sopenharmony_ci      .columnsGap(0)  
50e41f4b71Sopenharmony_ci      .rowsGap(0)  
51e41f4b71Sopenharmony_ci      .size({ width: "100%", height: "100%" })  
52e41f4b71Sopenharmony_ci    }  
53e41f4b71Sopenharmony_ci  }  
54e41f4b71Sopenharmony_ci}
55e41f4b71Sopenharmony_ci```
56e41f4b71Sopenharmony_ci
57e41f4b71Sopenharmony_ci#### Recording Data
58e41f4b71Sopenharmony_ci
59e41f4b71Sopenharmony_ciTo record data with FrameTimeline, perform the following steps:
60e41f4b71Sopenharmony_ci
61e41f4b71Sopenharmony_ci1. Choose **Record template** > **Trace template** and enable **FrameTimeline**.
62e41f4b71Sopenharmony_ci
63e41f4b71Sopenharmony_ci	**Figure 2** Enabling the FrameTimeline frame
64e41f4b71Sopenharmony_ci
65e41f4b71Sopenharmony_ci	![](./figures/smartperf-host-using-2.png)
66e41f4b71Sopenharmony_ci
67e41f4b71Sopenharmony_ci2. Customize the recording settings.
68e41f4b71Sopenharmony_ci
69e41f4b71Sopenharmony_ci	**Figure 3** Recording settings
70e41f4b71Sopenharmony_ci
71e41f4b71Sopenharmony_ci	![](./figures/smartperf-host-using-3.png)
72e41f4b71Sopenharmony_ci
73e41f4b71Sopenharmony_ci3. Click **Record** in the upper right corner to start recording. At the same time, interact with the test device to reproduce the frame loss or frame freezing. When the recording is complete, the page automatically loads the trace data.
74e41f4b71Sopenharmony_ci
75e41f4b71Sopenharmony_ci**NOTE**
76e41f4b71Sopenharmony_ci
77e41f4b71Sopenharmony_ci- During data recording and analysis, do not exit the application or power off the device. Otherwise, the analysis may fail.
78e41f4b71Sopenharmony_ci
79e41f4b71Sopenharmony_ci- After you click **Record**, if "please kill other hdc-server!" is displayed on the top of the web page, the HDC port of the device is in use. In this case, run **hdc kill** in the CLI and reconnect to the device to try again.
80e41f4b71Sopenharmony_ci
81e41f4b71Sopenharmony_ci#### Analyzing Data
82e41f4b71Sopenharmony_ci
83e41f4b71Sopenharmony_ciA complete rendering process is as follows: The application responds to the user input, completes UI drawing, and submits the UI drawing to Render Service, which then coordinates resources such as the GPU to complete rendering, synthesis, and display. During this process, frame freezing and subsequent frame loss may occur on both the application and Render Service sides.
84e41f4b71Sopenharmony_ci
85e41f4b71Sopenharmony_ciBased on the three groups of data shown in Figure 4, Figure 5, and Figure 6, you can quickly locate where frame loss occurs and complete preliminary demarcation.
86e41f4b71Sopenharmony_ci
87e41f4b71Sopenharmony_ci**Figure 4** Total time consumed by the UI and RenderService
88e41f4b71Sopenharmony_ci
89e41f4b71Sopenharmony_ci![](./figures/smartperf-host-using-4.png) 
90e41f4b71Sopenharmony_ci
91e41f4b71Sopenharmony_ci  
92e41f4b71Sopenharmony_ci**Figure 5** Time consumed by the UI
93e41f4b71Sopenharmony_ci
94e41f4b71Sopenharmony_ci![](./figures/smartperf-host-using-5.png) 
95e41f4b71Sopenharmony_ci
96e41f4b71Sopenharmony_ci  
97e41f4b71Sopenharmony_ci**Figure 6** Time consumed by RenderService
98e41f4b71Sopenharmony_ci
99e41f4b71Sopenharmony_ci![](./figures/smartperf-host-using-6.png) 
100e41f4b71Sopenharmony_ci
101e41f4b71Sopenharmony_ci- **Expected Timeline** represents the expected, ideal timeline, and **Actual Timeline** the actual timeline.
102e41f4b71Sopenharmony_ci
103e41f4b71Sopenharmony_ci- There are three types of frames in the timeline: Green frames are normal frames, orange frames are janky frames, and yellow frames are where the interaction between the application and Render Service is abnormal.
104e41f4b71Sopenharmony_ci
105e41f4b71Sopenharmony_ci- In the preceding figures, the length of each frame indicates the amount of time spent on the frame.
106e41f4b71Sopenharmony_ci
107e41f4b71Sopenharmony_ci- If the actual end time of a frame on the application or Render Service side is later than the expected deadline, it is considered as a janky frame.
108e41f4b71Sopenharmony_ci
109e41f4b71Sopenharmony_ci- If there are orange frames on the application side, check whether the processing logic of the UI thread is too complex or inefficient and whether resources are preempted by other tasks.
110e41f4b71Sopenharmony_ci
111e41f4b71Sopenharmony_ci- If there are orange frames on the Render Service side, check whether the GUI layout is too complex. You can use ArkUI Inspector and [HiDumper](../performance/performance-optimization-using-hidumper.md) to analyze and locate the fault.
112e41f4b71Sopenharmony_ci
113e41f4b71Sopenharmony_ciIn this example, as shown in Figure 5 and Figure 6, the frame freezing issue lies in the application side. Click a janky frame for detailed analysis. The associated frames are represented through lines, and the details of the frame are displayed under **Current Selection**, as shown in Figure 7.
114e41f4b71Sopenharmony_ci
115e41f4b71Sopenharmony_ci**Figure 7** Frame freezing in the application
116e41f4b71Sopenharmony_ci
117e41f4b71Sopenharmony_ci![](./figures/smartperf-host-using-7.png)
118e41f4b71Sopenharmony_ci
119e41f4b71Sopenharmony_ci- **Duration** indicates the amount of time spent on the frame.
120e41f4b71Sopenharmony_ci
121e41f4b71Sopenharmony_ci- **Jank Type** indicates the janky frame type. **APP Deadline Missed** indicates that the janky frame occurs on the application side.
122e41f4b71Sopenharmony_ci
123e41f4b71Sopenharmony_ci- **FrameTimeLine flows Slice** indicates the associated frame in **FrameTimeLine**.
124e41f4b71Sopenharmony_ci
125e41f4b71Sopenharmony_ci- **Preceding flows Slice** indicates the associated frame in Render Service.
126e41f4b71Sopenharmony_ci
127e41f4b71Sopenharmony_ciIn the following figure that shows the expanded application lanes, there are two lanes with the same name and PID. The first lane indicates the thread usage, and the second lane indicates the call stack in the thread. Based on the trace data of the time corresponding to the janky frame, it can be discerned that the FlushLayoutTask, which re-measures and lays out items, is time consuming. A closer look reveals that Layout[Gird] takes the longest time. Therefore, it is safe to conclude that the frame freezing can be ascribed to the gird layout processing logic being too complex or inefficient.
128e41f4b71Sopenharmony_ci
129e41f4b71Sopenharmony_ci**Figure 8** Application layout drawing trace data
130e41f4b71Sopenharmony_ci
131e41f4b71Sopenharmony_ci![](./figures/smartperf-host-using-8.png) 
132e41f4b71Sopenharmony_ci
133e41f4b71Sopenharmony_ciAfter locating and analyzing the grid layout code segment, we can optimize the code as follows: Remove the redundant three-layer stack container, pre-convert the source data to the string type required the layout, and add the **cachedCount** parameter to the **\<Grid>** component to work with the **LazyForEach** syntax for pre-loading. Set **cachedCount** to the number of grid items that can be rendered on one screen. After the optimization, let's record data in the same way. As shown in Figure 9, no frame freezing or frame loss occurs during swiping.
134e41f4b71Sopenharmony_ci
135e41f4b71Sopenharmony_ci**Figure 9** FrameTimeline diagram after optimization
136e41f4b71Sopenharmony_ci
137e41f4b71Sopenharmony_ci![](./figures/smartperf-host-using-9.png) 
138e41f4b71Sopenharmony_ci
139e41f4b71Sopenharmony_ciThe code after optimization is as follows:
140e41f4b71Sopenharmony_ci
141e41f4b71Sopenharmony_ci```
142e41f4b71Sopenharmony_ciclass MyDataSource implements IDataSource { // LazyForEach data source 
143e41f4b71Sopenharmony_ci  private list: string[] = [];  
144e41f4b71Sopenharmony_ci  
145e41f4b71Sopenharmony_ci  constructor(list: string[]) {  
146e41f4b71Sopenharmony_ci    this.list = list;  
147e41f4b71Sopenharmony_ci  }  
148e41f4b71Sopenharmony_ci  
149e41f4b71Sopenharmony_ci  totalCount(): number {  
150e41f4b71Sopenharmony_ci    return this.list.length;  
151e41f4b71Sopenharmony_ci  }  
152e41f4b71Sopenharmony_ci  
153e41f4b71Sopenharmony_ci  getData(index: number): string {  
154e41f4b71Sopenharmony_ci    return this.list[index];  
155e41f4b71Sopenharmony_ci  }  
156e41f4b71Sopenharmony_ci  
157e41f4b71Sopenharmony_ci  registerDataChangeListener(_: DataChangeListener): void {  
158e41f4b71Sopenharmony_ci  }  
159e41f4b71Sopenharmony_ci  
160e41f4b71Sopenharmony_ci  unregisterDataChangeListener(): void {  
161e41f4b71Sopenharmony_ci  }  
162e41f4b71Sopenharmony_ci}  
163e41f4b71Sopenharmony_ci@Entry  
164e41f4b71Sopenharmony_ci@Component  
165e41f4b71Sopenharmony_cistruct Index {  
166e41f4b71Sopenharmony_ci  @State children: string[] = Array.from<undefined, string>(Array(2000).fill(undefined), (_v: undefined, k) => k.toString());  
167e41f4b71Sopenharmony_ci  @State data: MyDataSource = new MyDataSource(this.children)  
168e41f4b71Sopenharmony_ci  build() {  
169e41f4b71Sopenharmony_ci    Scroll() {  
170e41f4b71Sopenharmony_ci      Grid() {  
171e41f4b71Sopenharmony_ci        LazyForEach(this.data, (item: string) => {  
172e41f4b71Sopenharmony_ci          GridItem() {  
173e41f4b71Sopenharmony_ci            Text(item)  
174e41f4b71Sopenharmony_ci              .fontSize(32)  
175e41f4b71Sopenharmony_ci          }  
176e41f4b71Sopenharmony_ci        }, (item: string) => item)  
177e41f4b71Sopenharmony_ci      }  
178e41f4b71Sopenharmony_ci      .cachedCount(80)  
179e41f4b71Sopenharmony_ci      .columnsTemplate('1fr 1fr 1fr 1fr')  
180e41f4b71Sopenharmony_ci      .columnsGap(0)  
181e41f4b71Sopenharmony_ci      .rowsGap(0)  
182e41f4b71Sopenharmony_ci      .size({ width: "100%", height: "100%" })  
183e41f4b71Sopenharmony_ci    }  
184e41f4b71Sopenharmony_ci  }  
185e41f4b71Sopenharmony_ci}
186e41f4b71Sopenharmony_ci```
187e41f4b71Sopenharmony_ci
188e41f4b71Sopenharmony_ci### AppStartup: Application Startup Analysis
189e41f4b71Sopenharmony_ci
190e41f4b71Sopenharmony_ciThe AppStartup feature provides the time consumption of each phase during application startup. With the provided data, you can discover which phase is slowing down your application startup and the time-consuming call stacks on the system side.
191e41f4b71Sopenharmony_ci
192e41f4b71Sopenharmony_ci#### Example
193e41f4b71Sopenharmony_ci
194e41f4b71Sopenharmony_ciThis example shows how the AppStartup feature works.
195e41f4b71Sopenharmony_ci
196e41f4b71Sopenharmony_ci```
197e41f4b71Sopenharmony_ci@Entry  
198e41f4b71Sopenharmony_ci@Component  
199e41f4b71Sopenharmony_cistruct Index {  
200e41f4b71Sopenharmony_ci  @State private text: string = "hello world";  
201e41f4b71Sopenharmony_ci  private count: number = 0;  
202e41f4b71Sopenharmony_ci  
203e41f4b71Sopenharmony_ci  aboutToAppear() {  
204e41f4b71Sopenharmony_ci    this.computeTask();  
205e41f4b71Sopenharmony_ci  }  
206e41f4b71Sopenharmony_ci  
207e41f4b71Sopenharmony_ci  build() {  
208e41f4b71Sopenharmony_ci    Column({space: 10}) {  
209e41f4b71Sopenharmony_ci      Text(this.text).fontSize(50)  
210e41f4b71Sopenharmony_ci    }  
211e41f4b71Sopenharmony_ci    .width('100%')  
212e41f4b71Sopenharmony_ci    .height('100%')  
213e41f4b71Sopenharmony_ci    .padding(10)  
214e41f4b71Sopenharmony_ci  }  
215e41f4b71Sopenharmony_ci  
216e41f4b71Sopenharmony_ci  computeTask() {  
217e41f4b71Sopenharmony_ci    this.count = 0;  
218e41f4b71Sopenharmony_ci    while (this.count < 10000000) {  
219e41f4b71Sopenharmony_ci      this.count++;  
220e41f4b71Sopenharmony_ci    }  
221e41f4b71Sopenharmony_ci  }  
222e41f4b71Sopenharmony_ci}
223e41f4b71Sopenharmony_ci```
224e41f4b71Sopenharmony_ci
225e41f4b71Sopenharmony_ci#### Recording Data
226e41f4b71Sopenharmony_ci
227e41f4b71Sopenharmony_ciTo record data with AppStartup, perform the following steps:
228e41f4b71Sopenharmony_ci
229e41f4b71Sopenharmony_ci1. Switch to the **Flags** page and set **AppStartup** to **Enabled**.
230e41f4b71Sopenharmony_ci
231e41f4b71Sopenharmony_ci	**Figure 10** Enabling AppStartup
232e41f4b71Sopenharmony_ci
233e41f4b71Sopenharmony_ci	![](./figures/smartperf-host-using-10.png) 
234e41f4b71Sopenharmony_ci
235e41f4b71Sopenharmony_ci2. Switch to the **Record template** page, click **Trace template**, and enable **AppStartup**.
236e41f4b71Sopenharmony_ci
237e41f4b71Sopenharmony_ci	**Figure 11** Enabling the AppStartup template
238e41f4b71Sopenharmony_ci
239e41f4b71Sopenharmony_ci	![](./figures/smartperf-host-using-11.png) 
240e41f4b71Sopenharmony_ci
241e41f4b71Sopenharmony_ci3. On the **Record setting** tab, customize the recording settings.
242e41f4b71Sopenharmony_ci
243e41f4b71Sopenharmony_ci	**Figure 12** Recording settings
244e41f4b71Sopenharmony_ci
245e41f4b71Sopenharmony_ci	![](./figures/smartperf-host-using-12.png) 
246e41f4b71Sopenharmony_ci
247e41f4b71Sopenharmony_ci4. Click **Record** in the upper right corner to start recording. At the same time, open the target application on the device. To end the recording, click **StopRecord**. Alternatively, wait until the recording is complete automatically. When the recording is complete, the page automatically loads the trace data.
248e41f4b71Sopenharmony_ci
249e41f4b71Sopenharmony_ci	**Figure 13** Ending recording
250e41f4b71Sopenharmony_ci
251e41f4b71Sopenharmony_ci	![](./figures/smartperf-host-using-13.png) 
252e41f4b71Sopenharmony_ci
253e41f4b71Sopenharmony_ci#### Analyzing Data
254e41f4b71Sopenharmony_ci
255e41f4b71Sopenharmony_ciWait until the analysis result is automatically generated. Click the filter button in the upper right corner and select **AppStartup** to view and analyze data.
256e41f4b71Sopenharmony_ci
257e41f4b71Sopenharmony_ci**Figure 14** Filtering template data
258e41f4b71Sopenharmony_ci
259e41f4b71Sopenharmony_ci![](./figures/smartperf-host-using-14.png) 
260e41f4b71Sopenharmony_ci
261e41f4b71Sopenharmony_ciExpand the lane of the corresponding application and locate the time frame in which the application is started. Select all phases of the AppStartup lane. You can view the time consumption of each phase in the lower pane.
262e41f4b71Sopenharmony_ci
263e41f4b71Sopenharmony_ci**Figure 15** Time required for each AppStartup phase (before optimization)
264e41f4b71Sopenharmony_ci
265e41f4b71Sopenharmony_ci![](./figures/smartperf-host-using-15.png) 
266e41f4b71Sopenharmony_ci
267e41f4b71Sopenharmony_ci- **ProcessTouchEvent**: input and processing of click events
268e41f4b71Sopenharmony_ci
269e41f4b71Sopenharmony_ci- **StartUIAbilityBySCB**: process information and window creation
270e41f4b71Sopenharmony_ci
271e41f4b71Sopenharmony_ci- **LoadAbility**: process startup
272e41f4b71Sopenharmony_ci
273e41f4b71Sopenharmony_ci- **Application Launching**: application loading
274e41f4b71Sopenharmony_ci
275e41f4b71Sopenharmony_ci- **UI Ability Launching**: UI ability loading
276e41f4b71Sopenharmony_ci
277e41f4b71Sopenharmony_ci- **UI Ability OnForeground**: application being switched to the foreground.
278e41f4b71Sopenharmony_ci
279e41f4b71Sopenharmony_ci- **First Frame - App Phase**: submission of the first frame for rendering – application
280e41f4b71Sopenharmony_ci
281e41f4b71Sopenharmony_ci- **First Frame - Render Phase**: submission of the first frame for rendering – Render Service
282e41f4b71Sopenharmony_ci
283e41f4b71Sopenharmony_ciAs shown in the preceding figure, the **UI Ability OnForeground** phase takes the longest time, which is 323 ms.
284e41f4b71Sopenharmony_ci
285e41f4b71Sopenharmony_ci**Figure 16** Time required for the **UI Ability OnForeground** phase (before optimization)
286e41f4b71Sopenharmony_ci
287e41f4b71Sopenharmony_ci![](./figures/smartperf-host-using-16.png) 
288e41f4b71Sopenharmony_ci
289e41f4b71Sopenharmony_ciA closer look at the phase data reveals that the **aboutToAppear** lifecycle callback takes a long time, which is 268 ms, accounting for 82% of the time consumed by the entire **UI Ability OnForeground** phase.
290e41f4b71Sopenharmony_ci
291e41f4b71Sopenharmony_ci**Figure 17** Time required for **aboutToAppear** (before optimization)
292e41f4b71Sopenharmony_ci
293e41f4b71Sopenharmony_ci![](./figures/smartperf-host-using-17.png) 
294e41f4b71Sopenharmony_ci
295e41f4b71Sopenharmony_ciIt is found in the code that a time-consuming calculation task is executed in the **aboutToAppear** lifecycle callback. This task slows down the cold start of the application.
296e41f4b71Sopenharmony_ci
297e41f4b71Sopenharmony_ciTo speed up application startup, we can conduct asynchronous processing for **aboutToAppear**. The code after optimization is as follows:
298e41f4b71Sopenharmony_ci
299e41f4b71Sopenharmony_ci```
300e41f4b71Sopenharmony_ci@Entry  
301e41f4b71Sopenharmony_ci@Component  
302e41f4b71Sopenharmony_cistruct Index {  
303e41f4b71Sopenharmony_ci  @State private text: string = "hello world";  
304e41f4b71Sopenharmony_ci  private count: number = 0;  
305e41f4b71Sopenharmony_ci  
306e41f4b71Sopenharmony_ci  aboutToAppear() {  
307e41f4b71Sopenharmony_ci    setTimeout(() => {  
308e41f4b71Sopenharmony_ci      this.computeTask();  
309e41f4b71Sopenharmony_ci    }, 0)  
310e41f4b71Sopenharmony_ci  }  
311e41f4b71Sopenharmony_ci  
312e41f4b71Sopenharmony_ci  build() {  
313e41f4b71Sopenharmony_ci    Column({space: 10}) {  
314e41f4b71Sopenharmony_ci      Text(this.text).fontSize(10)  
315e41f4b71Sopenharmony_ci    }  
316e41f4b71Sopenharmony_ci    .width('100%')  
317e41f4b71Sopenharmony_ci    .height('100%')  
318e41f4b71Sopenharmony_ci    .padding(10)  
319e41f4b71Sopenharmony_ci  }  
320e41f4b71Sopenharmony_ci  
321e41f4b71Sopenharmony_ci  computeTask() {  
322e41f4b71Sopenharmony_ci    this.count = 0;  
323e41f4b71Sopenharmony_ci    while (this.count < 10000000) {  
324e41f4b71Sopenharmony_ci      this.count++;  
325e41f4b71Sopenharmony_ci    }  
326e41f4b71Sopenharmony_ci  }  
327e41f4b71Sopenharmony_ci}
328e41f4b71Sopenharmony_ci```
329e41f4b71Sopenharmony_ci
330e41f4b71Sopenharmony_ciNow, let's record the data in the same way.
331e41f4b71Sopenharmony_ci
332e41f4b71Sopenharmony_ci**Figure 18** Time required for each AppStartup phase (after optimization)
333e41f4b71Sopenharmony_ci
334e41f4b71Sopenharmony_ci![](./figures/smartperf-host-using-18.png) 
335e41f4b71Sopenharmony_ci
336e41f4b71Sopenharmony_ciThe focus of optimization, the **UI Ability OnForeground** phase, where the **aboutToAppear** lifecycle is located, takes 81 ms.
337e41f4b71Sopenharmony_ci
338e41f4b71Sopenharmony_ci**Figure 19** Time required for the UI Ability OnForeground phase (after optimization)
339e41f4b71Sopenharmony_ci
340e41f4b71Sopenharmony_ci![](./figures/smartperf-host-using-19.png) 
341e41f4b71Sopenharmony_ci
342e41f4b71Sopenharmony_ciA closer look at the phase data reveals that the **aboutToAppear** lifecycle callback now takes 2 ms, accounting for only 2.5% of the time consumed by the entire **UI Ability OnForeground** phase.
343e41f4b71Sopenharmony_ci
344e41f4b71Sopenharmony_ci**Figure 20** Time consumed by aboutToAppear (after optimization)
345e41f4b71Sopenharmony_ci
346e41f4b71Sopenharmony_ci![](./figures/smartperf-host-using-20.png)
347