1, perceptual Lag
User perception of the lag, mainly from the interface refresh. The performance of the interface is mainly dependent on the UI rendering performance of the device. If our UI design is too complex, or the implementation is not good enough, the device does not give force, the interface will be like stuck, the feeling of the user lag.
1.1 16ms Principle
Before we analyze the reasons for the lag, let's look at the famous "16ms" principle in Android:
The Android system emits a vsync signal to redraw our interface (Activity) every 16ms.
Why 16ms, because Android set the refresh rate is 60FPS (frame per Second), that is, 60 frames per second refresh rate, about 16ms refresh once.
It's like this:
16ms
This means that we need to complete the next operation of the interface to be refreshed within 16ms so that the interface refreshes the update. But what if we can't finish the operation within 16ms?
For example, suppose we update the background image of the screen, we need 24ms to do this operation. When the system refreshes the interface at the first 16ms, but our operation is not over yet, we cannot draw the picture. The updated image is only visible to the user when the system is re-vsync at 16ms, again, when the interface is redrawn. That means the user is 32ms after seeing this refresh (note, not 24ms). This is the legendary drop frame (dropped frame):
Dropped frame
Dropped frames to the user's feeling is the lag, and if the operation is too complex, dropped frames will be more, resulting in the interface is often stuck, stuck to explode.
So what are the common situations that will cause the operation to exceed 16ms, and then drop frames, so that users feel stuck?
2, causes analysis and treatment of cotton lag
In general, there are a few things that can lead to this performance problem, and we look at each of the following:
2.1 Overly complex layouts
As mentioned in the previous section, interface performance depends on UI rendering performance. We can understand that the entire process for UI rendering is done in conjunction with two parts of the CPU and GPU.
Among them, the CPU is responsible for the UI layout elements of measure, layout, draw and other related operations execution. The GPU is responsible for rasterization (Rasterization), drawing UI elements onto the screen.
If our UI layout is too deep , or if there is a complex operation in the OnDraw of the custom control , the CPU may be more computationally relevant than 16ms, resulting in the result.
At this point, we need to use the Hierarchy Viewer tool to help us analyze the layout. The Hierarchy Viewer not only shows the UI hierarchy as a graphical tree structure , but also gives three small dots for each node to indicate the time-consuming and performance of the element measure, Layout, draw.
Please refer to the App optimization layout for details.
2.2 Over-rendering (overdraw)
The CPU aspect of the above section, about GPU drawing, if our interface exists Overdraw, can also lead to Kaka.
Overdraw: Used to describe how many times a pixel is redrawn on the screen in a frame.
Popular saying: Ideally, each screen per frame, each pixel should only be drawn once, if there are many times to draw, is overdraw, over-drawn.
2.2.1 Debug Overdraw
The Android system provides a visual solution to make it easy to see the overdraw phenomenon:
Turn on debugging in System settings--Developer options--debugging GPU over-drawing:
Toggle GPU Overdraw
At this point the interface may be identified with five colors:
Overdraw indicator
- Primary color: No overdraw
- Blue: 1 times overdraw
- Green: 2 times Overdraw
- Pink: 3 times Overdraw
- Red: 4 times and more than 4 times of overdraw
In general, Blue is acceptable and performance is excellent.
Analysis and treatment of 2.2.2 Overdraw
There are words above, so-called Overdraw, which is plotted several times on a pixel point. The common is:
- Multiple backgrounds are drawn.
- Invisible UI elements are drawn.
Or use the code for this app as an example to debug, open the app and show it like this: Githubapp
Example-1
Can see is the middle list this piece of overdraw is more serious. View Code Discovery:
Fragment_trending_container.xml in Viewpager set the background:
<android.support.v4.view.ViewPager android:id="@+id/view_pager" android:background="@color/md_white_1000" android:layout_width="match_parent" android:layout_height="match_parent"/>
And the fragment in Viewpager set the background:
<?xml version= "1.0" Encoding= "utf-8" ?><android.support.v4.widget.swiperefreshlayout xmlns:android= "http://schemas.android.com/apk/res/android" android:id= "@+id/refresh_layout" android:background= "@color/md_white_1000" android:layout_width= "match_parent" Span class= "hljs-attr" >android:layout_height= "match_parent" > ... </android.support.v4.widget.swiperefreshlayout
Full code, please check the source on GitHub, this article analysis when the commit deadline to b01b5793.
Remove the background of the outer Viewpager and look again:
Example-2
You can see that the middle list area is no longer red, but it does not reach the acceptable level of blue. This is because our activity by default, theme will set the window to a solid color background. Because we don't want to use this default background here, we've added a background to layout, resulting in multiple drawing backgrounds.
Of course we can also customize the theme to set the theme window background to what we want instead of setting it in the layout.
The background of the window can be removed by the following way.
To set a theme:
<item name="android:windowBackground">@null</item>
or code settings, in OnCreate:
getWindow().setBackgroundDrawable(null);
At this point we see the effect:
Example-3
Has basically reached the level of optimization.
The above aims to provide analytical methods and ideas.
The main reason for Overdraw is the multiple drawing of the background, or the invisible view being drawn behind, but not limited to this.
2.3 Complex operations on UI threads
As discussed in the ANR correlation above, the complex operation of the UI thread will cause the UI to become unresponsive and, of course, cause the UI response to stall and lag.
The production of ANR is the ultimate in the lag, specific analysis can be viewed in the app optimization of the ANR detailed article.
For an analysis of the lag caused by operational congestion, you can use the TraceView tool.
Specific TraceView introduction, as well as actual combat analysis, can refer to the app optimization to enhance your app launch speed of the theoretical basis and app optimization to enhance your app launch speed of the instance challenge.
Here we need to mention the Strictmode we mentioned in the Performance analysis tool.
Use of 2.3.1 Strictmode
Strictmode is used to set policies based on threads or VMS, and once a policy violation is detected, the console outputs some warnings, including a trace message showing where your app is having problems.
Typically used to detect time-consuming operations such as disk read-write or network access in the main thread.
Open Strictmode in application or activity OnCreate:
public void oncreate () { if (buildconfig.debug) {//related policies for threads Strictmode.setthreadpolicy (new StrictMode.ThreadPolicy.Builder (). Detectdiskreads (). Detectdiskwrites (). Detectnetwork () //or. Detectall () for all detectable problems. Penaltylog (). build ()); //related policies for VMS Strictmode.setvmpolicy (new StrictMode.VmPolicy.Builder (). Detectleakedsqlliteobjects (). Detectleakedclosableobjects (). Penaltylog (). Penaltydeath (). build ()); } super.oncreate (),
If your thread is out of the question, the console will have a warning output that you can navigate to the code.
Relatively simple, here is not much nonsense.
To resolve the time-consuming operation of the UI thread, refer to the threading patterns mentioned in the ANR explanation.
2.4 Frequent GC
The above is all about processing, CPU, GPU-related. In fact, the memory causes may also cause the application to be not smooth, stutter.
Speaking of which, I think of the Big Three (CPU, memory, monitor) with the desktop. Looks like the Analysis app performance is also these big big ah:)
Why does frequent GC lead to stalling?
In short, when performing GC operations, any action on any thread will need to be paused, waiting for the GC operation to complete before other operations can continue , so if the program is frequently GC, it will naturally cause the interface to stutter.
The following information is referenced from Android performance Patterns:memory churn and performance. need FQ
There are two causes of frequent GC:
- Memory jitter (churn), in which a large number of objects are created and released immediately in a short period of time.
- Generating a large number of objects in an instant can seriously occupy young generation's memory area, and when the threshold is reached, the GC will also be triggered when there is not enough space left. Even though each allocated object requires little memory, stacking them together increases the pressure on the heap, triggering more GC.
These GC operations can cause the dropped frames mentioned above, as follows:
GC Dropped frame
will make the user aware of Kaka.
Generally, a large number of objects are generated in an instant because we are in the loop of the code to new objects, or to create objects in OnDraw. So these are the places that we especially need to be aware of ...
Android Card optimization 1 lag analysis