It is a common misconception that using the basic layout structures leads to the most efficient
layouts. However, each widget and layout you add to your application requires initialization,
layout, and drawing. For example, using nested instances of
lead to an excessively deep view hierarchy. Furthermore, nesting several instances of
LinearLayout that use the
layout_weight parameter can be especially
expensive as each child needs to be measured twice. This is particularly important when the layout
is inflated repeatedly, such as when used in a
Inspect Your Layout
The Android SDK tools include a tool called Hierarchy Viewer that allows you to analyze your layout while your application is running. Using this tool helps you discover bottlenecks in the layout performance.
Hierarchy Viewer works by allowing you to select running processes on a connected device or emulator, then display the layout tree. The traffic lights on each block represent its Measure, Layout and Draw performance, helping you identify potential issues.
For example, figure 1 shows a layout that's used as an item in a
ListView. This layout shows a small bitmap image on the left and two stacked items
of text on the right. It is especially important that layouts that will be inflated multiple
times—such as this one—are optimized as the performance
benefits will be multiplied.
hierarchyviewer tool is available in
<sdk>/tools/. When opened,
the Hierarchy Viewer shows a list of available devices and its running components. Click
Load View Hierarchy to view the layout hierarchy of the selected component. For
example, figure 2 shows the layout for the list item illustrated by figure 1.
In figure 2, you can see there is a 3-level hierarchy with some problems laying out the text items. Clicking on the items shows the time taken for each stage of the process (figure 3). It becomes clear which items are taking the longest to measure, layout, and render, and where you should spend time optimizing.
The timings for rendering a complete list item using this layout are:
- Measure: 0.977ms
- Layout: 0.167ms
- Draw: 2.717ms
Revise Your Layout
Because the layout performance above slows down due to a nested
LinearLayout, the performance might improve by flattening the layout—make
the layout shallow and wide, rather than narrow and deep. A
the root node allows for such layouts. So, when this design is converted to use
RelativeLayout, you can see that the layout becomes a 2-level hierarchy. Inspection
of the new layout looks like this:
Now rendering a list item takes:
- Measure: 0.598ms
- Layout: 0.110ms
- Draw: 2.146ms
Might seem like a small improvement, but this time is multiplied several times because this layout is used for every item in a list.
Most of this time difference is due to the use of
layout_weight in the
LinearLayout design, which can slow down the speed of measurement. It is just one
example of how each layout has appropriate uses and you should carefully consider whether using
layout weight is necessary.
It is always good practice to run the Lint tool on your layout files to search for possible view hierarchy optimizations. Lint has replaced the Layoutopt tool and has much greater functionality. Some examples of Lint rules are:
- Use compound drawables - A
LinearLayoutwhich contains an
TextViewcan be more efficiently handled as a compound drawable.
- Merge root frame - If a
FrameLayoutis the root of a layout and does not provide background or padding etc, it can be replaced with a merge tag which is slightly more efficient.
- Useless leaf - A layout that has no children or no background can often be removed (since it is invisible) for a flatter and more efficient layout hierarchy.
- Useless parent - A layout with children that has no siblings, is not a
ScrollViewor a root layout, and does not have a background, can be removed and have its children moved directly into the parent for a flatter and more efficient layout hierarchy.
- Deep layouts - Layouts with too much nesting are bad for performance. Consider using flatter layouts such as
GridLayoutto improve performance. The default maximum depth is 10.
Another benefit of Lint is that it is integrated into the Android Development Tools for Eclipse (ADT 16+). Lint automatically runs whenever you export an APK, edit and save an XML file or use the Layout Editor. To manually force Lint to run press the Lint button in the Eclipse toolbar.
When used inside Eclipse, Lint has the ability to automatically fix some issues, provide suggestions for others and jump directly to the offending code for review. If you don’t use Eclipse for your development, Lint can also be run from the command line. More information about Lint is available at tools.android.com.