Welcome toTencent Cloud + community, get more Tencent massive technology practice dry goods oh ~

This article was published in the Cloud + Community column by the WeTest Quality Open Platform team

In addition to amazing features and outrageous interactions, an app should also be silky in performance to enhance the user experience.


The following is a summary of the performance optimization I have experienced in my work. According to the development path of the story, it is divided into five parts: Common performance problems; Some possible causes of performance problems; Routines for solving performance problems; Code suggestions and potential performance problems.

If you can’t see the big picture, there will be a disassembly below

First, let’s look at some of the performance issues


1. Memory leak.

Generally speaking, a memory leak can not only cause an application to use too much memory, it can also cause an application to lag, resulting in a bad user experience. As to why a “small” memory leak can cause an application to lag, I have to use this picture as an example.

And that’s right, that’s the Generational Heap Memory model you need to understand when you’re working on Android children’s shoes. And that if they were younger, if they weren’t killed, they were moved into the Old Generation. Finally, it moves to Permanent Generation. If memory leaks, then, sorry, your memory will naturally enter Permanent Generation over time. However, there is a limit to how much memory you can allocate to your application because of the sandbox mechanism. You can’t get over it (someone laughed, there’s a large heap, and I laughed, too, and I don’t see it ever being used by the great Android players), well, your leaky object is in the manger, leaving less room for other objects to use; For example, the stage is small, the actor has to perform on the stage, there is no extra space, he can only wait for other actors to come down before he can perform ah, this waiting time, it is not continuous performance, so the card.

2. Frequent GC

Ha ha, frequent GC will cause lag, I think you have already known the reason after the baptism above, yes, of course, it is also because of “lack of stage space, new actors on stage need to let the performance down first”. So what causes this phenomenon?

A, memory leak, ok, you get it, don’t talk about it, this must be possible.

B, a large number of objects are created in a short period of time, and “need” to be released in a short period of time, note that this is needed, but also because “there is not enough stage space”, for example, in onDraw new objects, because onDraw will execute once (wait, can you make sure) What is about 16ms, sorry, can’t, drop frame is not, even if drop so little). Imagine, every second to create about 60 objects, well, you think Young Generation is cabbage, take as many as you want, sorry, there is a limited amount of, here run out, in the application, I have to go to recycle some back, I always recycle time, time, ok, If onDraw waits, it will miss the next 16ms execution. If so, the user will appear stuck.

3. Power consumption

Km is very sharp, there is a problem in a micro view small video look at mobile phone will be hot after a while, so that the user has always been very concerned about the problem of power consumption but sorry, our app has not experienced severe electricity problems, although there is no serious power consumption problems, do not represent don’t have to know the solution to this problem, I have:

A, there is no particularly important information, such as money, phone call, 100 yuan solid no threshold voucher method, etc., please do not disturb the user, do not frequently wake up the user, otherwise, the result can only be uninstalled, or close all notifications.

B. Do local caching properly and avoid frequent requests for network data. Here, it is easy to say, but it is not easy to do, with a good caching strategy, it is important to distinguish between what will not change for a period of time and what will never be cached.

C. Some long time synchronization operations are performed when the user is charging and wifi is available, unless the user forces synchronization.. Wait, not too much, because there’s a lot more to come.

4, OOM problem

Ha ha, this problem, must through the baptism of the front 1, 2, you should have understood what causes this, you can imagine, “an actor on the stage to is a big fat man, even if the actors don’t show off, he still can’t squeeze up, how to do, play failed, also what I can do, collapse, directly over!” There are possible causes of this problem. (Ha ha, to be on the safe side, I can only say that it is possible.)

A, memory leak, you must know a smile.

B, a large amount of invisible object memory, this in fact, very common, just may have been less a concern, for example, the request data interface is returned to the list of 100, each data such as the 100 field, including your user display data only 10 a few, but, when you parse, the remaining 99 unknowingly eat your memory, When a fat man asks for memory, hehe, burp fart.

C, there is a very common scene is a page multi-picture scene, clearly each picture only need to load a 100_100, but you use the original size (1080_1980) or larger, and you load dozens of pieces at a time, carry it? So take a look at inSampleSize, or, if you upload images to manage, you can use Vientil, which cuts out different sizes of images for you, so you don’t have to scale them on the client.

Above, we have looked at some performance problems. Here, we simply list the causes of these performance problems


1. A slight time-consuming operation is performed in the UI thread, causing the UI thread to stall

You can read pref and parse json data in onCreate, but that’s not the case. Instead, you can wrap these operations asynchronously. Rxjava2 is the latest version of rxJava. If you’re not sure how to use it, Google it.

2. Layout is too complex to complete rendering in 16ms

This is a lot of friends have deep experience, here a simple understanding, we first simple render roughly divided into “layout”,”measure””draw” such a few stages, of course, you do not think that the actual situation is the same, well, the hierarchy is complex, layout,measure may use the time should not be used, Naturally, there may not be enough time for Draw. Naturally, there is a tragedy. So a lot of the advice that was given was to use a RelativeLayout instead of a LinearLayout to reduce the layout hierarchy, so please don’t recommend using a RelativeLayout now, ConstraintLayout is a high performance way to eliminate the layout hierarchy. ConstraintLayout is based on the Cassowary algorithm, which has the advantage of being extremely efficient in solving linear equations. Linear equations have proven to be very suitable for defining the parameters of user interface elements. Because people are so sensitive to graphics, UI rendering speed is very important. So in 2016, both iOS and Android developed their own layout systems based on Cassowary algorithm. Here is the performance comparison between ConstraintLayout and the traditional layout RelativeLayout and LinearLayout. But here is the foreigner test data, the original text can refer to here. Demo also provides a test method, interested partners can try it.

Measurement/layout (milliseconds, average of 100 frames)

3. Too many animations are executed at the same time, resulting in excessive CPU or GPU load

The main reason for this is that animations tend to change the properties of the view so often that the displayList becomes invalid and a new displayList needs to be created. If there are too many animations, this is an overhead. If you want to learn more about this, see section 5 for more details.

4. Overdrawing of views.

View overdraw is one of the most common problems we have when writing layouts. It’s a mistake to overdraw a view, usually within a nested viewgroup, when you give it an unnecessary background. It is not too difficult to solve these problems. We can easily find these problems by opening the “Show GPU Overdraw” option through the developer option in the mobile Settings, and then try to get closer to the blue color.

5. The problem of excessive GC is not discussed here, as it has been very straightforward.

6. Slow execution due to resource loading.

There are two ways to avoid loading resources and use different scenarios.

A, preload, that is, before the path is loaded, ah, like x5 kernel.

B. It really needs to be loaded when it is used. Please give a progress bar, so that users do not have to wait and do not know when it will end, resulting in a bad user experience.

7. The worker thread has a wrong priority, causing it to preempt CPU time with the UI thread.

If you’re using Rxjava, be aware that setting the execution thread of a task can have a significant impact on your performance. If you’re not using Rxjava, don’t take it too seriously.

8. Static variables.

In order to get past the trap of an Intent only passing 1 MB or less of data, I set a static variable in my application that can be used by both activities to “pass (share) data.” Has the tail of the previous activity, and thus leaks. Not just these examples, but just to name a few:

A. Have you ever used static collections to save data?

B) A singleton’s Manger, such as managing AudioManger?

3. Since the analysis of encountered problems is available, then how to use various kinds of dao, stick and sword naturally to solve these problems


1. Excessive GPU rendering, positioning excessive rendering region

You can see the effect of “Show GPU Overdraw” and easily find out which block needs to be optimized. How to optimize it

A. Reduce the layout hierarchy. As mentioned above, replace the traditional layout with ConstraintLayout. ConstraintLayout if you don’t know ConstraintLayout, that’s ok. This article teaches you 15 minutes to understand how to use ConstraintLayout.

B) Check if there is an unnecessary background color setting. We often make a silly mistake by setting the background to the overridden parent view. In most cases, these backgrounds are unnecessary.

2, the main thread time-consuming operation troubleshooting.

A. Enable strictMode. In this way, the time-consuming operations of the main thread will be reported to Logcat in the form of alarms.

B, directly add @debuglog to suspect the object, check method execution time. DebugLog annotations need to introduce Hugo, an early work by JakeWharton, the god of Android. It is very convenient for monitoring the execution time of functions. You can add annotations directly to functions, but there is a disadvantage. It is the last version released by JakeWharton that does not support the release version to replace the monitoring code with an empty method. Therefore, I have posted a reference to the company’s maven repository, which is referenced in a similar way to the website, except that the address is: ‘com. Tencent. Tip: Hugo – plugin: 2.0.0 – the SNAPSHOT’.

3. Too much time consuming for measure and layout

ConstraintLayout, therefore, it is strongly recommended that you use ConstraintLayout to reduce the layout hierarchy. The problem is usually solved. If you find that there are performance problems, you can use traceView to observe the time consuming method. Let’s figure out why.

4, leakcany

This is the memory leak detection silver bullet, you should have used, need to remind is, pay attention

dependencies {

DebugImplementation ‘com. Squareup. Leakcanary: leakcanary – android: 1.5.4’

ReleaseImplementation ‘com. Squareup. Leakcanary: leakcanary – android – no – op: 1.5.4’

}

In this way, releaseImplementation guarantees that the monitoring code is removed from the release package. Otherwise, it generates a continuous catch memory snapshot, which itself affects performance.

5. Write code in onDraw

OnDraw is executed roughly every 16ms, so it’s a forloop in itself. If you have new objects in it, you’re unknowingly creating and releasing a lot of objects in a short period of time, and frequent GC can result in, well, memory jitter, and then, you get stuck. So the right thing to do is to put the object outside and new out.

6. Json deserialization problem

Json deserialization is the process of turning A JSON string into an object, which is time-consuming and memory consuming to parse if you have a large amount of data, especially if you have a large number of strings. The solution is:

A. Simplify fields, negotiate with the background, and remove unnecessary fields from relevant interfaces. Guaranteed minimum availability principle.

B. Use stream parsing. I have considered json parsing optimization before and found this on Stack Overflow. FromJson can be played like this, which can increase parsing efficiency by 25%.

7. Use of viewStub&merge.

Merge and viewStub are two common layout components that you are familiar with. For components that are only displayed under certain conditions, it is recommended to enclose them with viewstubs. In the same way, include a layout whose root layout is the same as the parent that introduced it. If you’re worried about preview effects, there’s no need to do this because you can

Tools :showIn=”” property, so that preview is displayed properly.

8. Load optimization

There is no too many technical points in the inside, is time-consuming operation encapsulation to asynchronous, but one thing have to mention is that attention should be paid to the problem of multiple processes, if your application is a process, you should be aware of your application the oncreate method will be executed multiple times, you don’t really want to be resource loaded multiple times, So you only load in the main process, and if there are some craters, maybe there are other processes that need that resource, and then this process doesn’t load that resource, and then it’s gone.

9. Refresh and optimize.

I mentioned this in my previous post, but here are two examples.

A, for the list of the item operation, such as the item point like, at this time should not let the whole list refresh, but should only refresh this item, compared to skilled use of recyclerView you, should understand how to operate, do not understand please see here, You will learn what is called a recyclerView partial refresh.

B. For more complex pages, I suggest that you do not write them in an activity, but use several fragments to assemble them. In this way, only a specific fragment can be refreshed when the module changes, instead of refreshing the whole page. But how do you share data between fragments? Okay, let me do this.

The Activity abstracts this part of the data into a LiveDataManger data for management, and then each Fragment obtains the LiveDataManger from the context of the Activity, and then operates. Notifies the activity of data changes, and so on. It’s a bit like Google’s LiveData. If you want to use Google’s LiveData, that’s fine, but it’s a simplified version. Project introduction

‘com. Tencent. Tip: simple_live_data: – the SNAPSHOT 1.0.1’

10. Animation optimization

The main point here is to use hardware acceleration for optimization, but be aware that after the animation is done, turn off the hardware acceleration, because turning it on is itself a cost. There is a picture below, the second one is compared with the first one, which is the comparison between the effect of animation when hardware acceleration is enabled and when it is not enabled. You can see that the rendering speed is obviously much faster after hardware acceleration is enabled. Is everything all right when hardware acceleration is enabled? The third graph actually shows that if your view is failing over and over again, it’s going to have performance problems, and you can see in the third graph that the blue part of the graph is getting a little bit better, which means that the DisplayList is failing over and over again, and if you want to know more about it, you can check it out here

// Set the layer type to hardwaremyView.setLayerType(View.LAYER_TYPE_HARDWARE, null); // Setup the animationObjectAnimator animator = ObjectAnimator.ofFloat(myView,View.TRANSLATION_X, 150); // Add a listener that does cleanupanimator.addListener(new AnimatorListenerAdapter() {undefined @Override public void onAnimationEnd(Animator animation) { myView.setLayerType(View.LAYER_TYPE_NONE, null); }});

11 Power consumption optimization

These are just suggestions;

A. If the positioning accuracy is not high, use wifi or mobile network for positioning. It is not necessary to enable GPS positioning.

B. Verify the availability of the network first before sending the network request. For example, when the user is in the state of 2G, the operation at this time is to view a large picture, which may be more than 200 K or even larger when downloaded.

The next few things are more relaxed, some code suggestions


I won’t go into detail here, just pick the part of the mark.

Pb ->model optimization here is not to repeat, there is how to optimize the previous.

Then I suggest using SparseArray instead of HashMap. This is Google’s suggestion, because SparseArray is less memory intensive than HashMap and performs better in certain conditions, mainly because it avoids automatic boxing of keys such as int to Integer, Internally, data is stored through two arrays, one for key and the other for value. In order to optimize performance, data is compressed to represent sparse array data, thus saving memory space.

Don’t use wrap_content unless you have to, match_parent, or fixed size, with gravity=”center”, you get the idea.

So why is this better?

Because in the measurement process, match_parent and fixed width height correspond to EXACTLY, while WRap_content corresponds to AT_MOST, which takes more time to compare with AT_MOST.

Five summarizes


This is the above summary of the performance problems I encountered in my work and some of the treatment, performance optimization design is too many aspects, this article can not be all the performance problems all summed up clearly, there may be more or less some flaws, there are not welcome to point out the supplement.


The resources

Developers. Googleblog. Cn / 2017/09 / con… Etc., see the original article for details.

Question and answer

How do I publish node applications?

reading

2. A brief history of game artificial intelligence

Game artificial intelligence reading notes (I) Introduction and introduction

How is the extreme Crash rate lower than 0.01% achieved?

Cloud, college courses, recommend | zhihu KOL, choose to share with you in the machine learning how to do

This article has been published by Tencent Cloud + community authorized by the authorClick on the

Search concerned public number “cloud community”, the first time to obtain technical dry goods, after attention to reply 1024 send you a technical course gift package!

Massive technical practice experience, all in yunjia community!