Currently I am running into a performance issue, with one of my activitys.
In this Activity I am inflating a lot.
So beside optimizing the code I would like to optimize the layout, too.
The basic ideas are clear (avoid nesting, flat hirachie, viewStub where usefull, merge for the basic frame, ...). But still at some points you have to choose (like do I use a relative layout or a linear layout, a table layout or even a gridlayout).
Here is where my questions fit in:
How do I compare the efficiency of differend ways (that are giving me a similar layout)?
What I am already doing is to check the layout with the Hierarchy View, which gives me a general idea, which parts of the layout are expensive and which aren't.
BUT:
It does not give me an accurate comparission between different ways to do one thing. One and the same layout inflation can vary between 1ms and 20ms, even if it is the same layout only at a different time.
So my question: How do I compare different ways to achieve a layout for their efficiency, regardless of external circumstances?
Try using the layoutopt tool for the layout optimization.
If the view layout optimized enough then at runtime creating more views with the same layout should be optimized.
Related
I had been using nested views in one of the screens in my android app. Now that I have removed all of them and used a ConstraintLayout for performance gains, I want to measure how much the performance has increased. Is there a way to measure the performance gain?
The easiest way is probably just to profile the app using a profiler using the old code and the new and see how much inclusive time is spent in onLayout in both versions.
Expect the difference to be less dramatic than you expect. The reality is your main thread is going to be idle most of the time, improving layout efficiency is really rarely a big factor in your app's performance. I would never refactor a nested design for that, I'd refactor a nested design if using constraint layout gave me cleaner XML for my view. Also remember that depending on what features you use, constraint view may not be faster. Its quicker to layout a nested linear layout than it is to calculate a whole bunch of constraints on multiple inner views, for example.
I'm familiar with almost all the basic layouts in Android & understand when they are to be used. I know that a RelativeLayout is to be used when elements in the UI are to positioned relative to each other, that a LinearLayout is to be used when UI elements are to be displayed vertically or horizontally. So I was wondering if the ease of development was the only factor that determined what layout should be selected or if there was any performance factor involved. I mean I can lay out two ImageViews vertically in Android using both LinearLayout and RelativeLayout, so why use a particular layout then?
There are some performance gains for avoiding certain things, such as nesting RelativeLayout (see this question). Also, the docs recommend making layouts shallow and wide, which can facilitated with RelativeLayout, again for performance reasons.
However, often thinking about such things will be premature optimization for simple layouts, and you should use whatever makes the most sense for the situation.
For a long time I heard that RelativeLayouts are slow. In a couple of talks I recall hearing that this type of layout calls onMeasure twice and that for some reason is a drag to performance.
However, I am taking a performance course at udacity and I watched the following video:
https://www.youtube.com/watch?time_continue=303&v=gK9tdeqqigE
Here, the instructor used the Hierarchy viewer tool to compare the rendering cost of the same viewgroup using a relative layout and nested linear layouts.
In the video, the relativelayout is the clear winner, which contradicts everything that I have heard until now about the issue.
Could you please help me to understand in which circumstances each approach is better?
Thank you
That's a very broad question and there's no single, simple answer. LinearLayout is generally simpler (and therefore faster) than RelativeLayout, but LinearLayout has a problematic case if you nest multiple of them inside each other, with weights on the same axis. Then it has to iteratively divide up the space and this takes lots of layout passes (it's so bad there's a lint warning against this).
Even when you avoid that case, then with nested LinearLayouts you will still have a deeper view hierarchy compared to using RelativeLayout, so while LinearLayout is faster, that balances out at some point.
So it becomes the same thing as with all things performance: the only way to be absolutely sure is to measure and see what happens.
I'm prone to abusing LinearLayout, every screens there's usually three or four-level deep. Layout's design usually given size in percentages. Graphic cut to pieces and not utilizing 9-Patch. All of these resulting in me using layout_weight to represent percentages almost everywhere. Today I updated ADT and Lint has this nested weights warning everywhere. Now I'm really concern about the performance if I carry this habit into a bigger application. Is there a better way to do it without changing anything from designer's side?
If I start to get too many layers of LinearLayouts I tend to switch to a RelativeLayout at the root and most of the children only 1 layer removed from root.
9-Patch resources are very helpful also. I suggest you start to make use of those more.
Got a performance issue when lots of nested RelativeLayouts are used.
For example if we have some RelativeLayout as a UI root, and every container(button, label, textview, imageview) is a RelativeLayout + Android based component (ex. aButton = RelativeLayout + ImageView + TextView), then in a complex view of 4 buttons, 3 images and 6 labels we get ~15 nested RelativeLayouts.
RelativeLayout has a very complex onMeasure method, that calculates size of every child to determine the size of layout. Calculating size of a complex view of 15-20 nested RelativeLayouts costs ~5 seconds, that's too much. onMeasure is most expensive of all calls, even drawing finished much faster then measurement.
<=UPD=>
To prevent appearing suggestions to use native android views to build something complex: Ability to add everything to everything is required. That's why every container has to be not just View, but ViewGroup. And RelativeLayout features like gravity and alignment can also help alot, that's why lot's of RelativeLayouts are used.
<=/UPD=>
Had anyone got these performance problems?
Should replacing RelativeLayout with some other Layout solve issue?
Or removing all these nested layouts is the only way to deal with the problem?
Does anyone know how much layouts can be nested without some performance problems appearing?
It definitely depends on your testing device. But you should check the hierarchyviewer (within the tools directory) for unneccessary nests of views in order to remove them.
Also your aButton sounds like a stock ImageButton. So you could replace at least that with a standard solution.
If you posted some code it might be easier to tell whether there are more items that could be replaced by stock solutions.
After a few tests came to conclusion that having more that 12 nested layouts does a great impact on performance.
On average 10-11 nested layouts should work fine.
For example 12 nested layouts with 12 children on each display in 6 seconds on device, and in 9 on emulator.
It was my understanding that the whole point of relativelayout is that you don't have to nest them to the nth degree. Why not just use a few RelativeLayout s rather than 1 per component?