Home | History | Annotate | Download | only in improving-layouts
      1 page.title=Optimizing Layout Hierarchies
      2 parent.title=Improving Layout Performance
      3 parent.link=index.html
      4 
      5 trainingnavtop=true
      6 next.title=Re-using Layouts with <include/>
      7 next.link=reusing-layouts.html
      8 
      9 @jd:body
     10 
     11 
     12 
     13 <div id="tb-wrapper">
     14 <div id="tb">
     15 
     16 <!-- table of contents -->
     17 <h2>This lesson teaches you to</h2>
     18 <ol>
     19   <li><a href="#Inspect">Inspect Your Layout</a></li>
     20   <li><a href="#Revise">Revise Your Layout</a></li>
     21   <li><a href="#Lint">Use Lint</a></li>
     22 </ol>
     23 
     24 <!-- other docs (NOT javadocs) -->
     25 <h2>You should also read</h2>
     26 <ul>
     27   <li><a href="{@docRoot}guide/topics/ui/declaring-layout.html">XML Layouts</a></li>
     28   <li><a
     29 href="{@docRoot}guide/topics/resources/layout-resource.html#include- element">Layout
     30 Resource</a></li>
     31 </ul>
     32 
     33 </div>
     34 </div>
     35 
     36 
     37 <p>It is a common misconception that using the basic layout structures leads to the most efficient
     38 layouts. However, each widget and layout you add to your application requires initialization,
     39 layout, and drawing. For example, using nested instances of {@link android.widget.LinearLayout} can
     40 lead to an excessively deep view hierarchy. Furthermore, nesting several instances of {@link
     41 android.widget.LinearLayout} that use the {@code layout_weight} parameter can be especially
     42 expensive as each child needs to be measured twice. This is particularly important when the layout
     43 is inflated repeatedly, such as when used in a {@link android.widget.ListView} or {@link
     44 android.widget.GridView}.</p>
     45 
     46 <p>In this lesson you'll learn to use <a
     47 href="{@docRoot}tools/help/hierarchy-viewer.html">Hierarchy Viewer</a> and <a
     48 href="{@docRoot}tools/help/layoutopt.html">Layoutopt</a> to examine and optimize your
     49 layout.</p>
     50 
     51 
     52 
     53 <h2 id="Inspect">Inspect Your Layout</h2>
     54 
     55 <p>The Android SDK tools include a tool called <a
     56 href="{@docRoot}tools/help/hierarchy-viewer.html">Hierarchy Viewer</a> that allows
     57 you to analyze your layout while your application is running. Using this tool helps you discover
     58 bottlenecks in the layout performance.</p>
     59 
     60 <p>Hierarchy Viewer works by allowing you to select running processes on a connected device or
     61 emulator, then display the layout tree. The traffic lights on each block represent its Measure,
     62 Layout and Draw performance, helping you identify potential issues.</p>
     63 
     64 <p>For example, figure 1 shows a layout that's used as an item in a {@link
     65 android.widget.ListView}. This layout shows a small bitmap image on the left and two stacked items
     66 of text on the right. It is especially important that layouts that will be inflated multiple
     67 times&mdash;such as this one&mdash;are optimized as the performance
     68 benefits will be multiplied.</p>
     69 
     70 <img src="{@docRoot}images/training/layout-listitem.png" alt="" />
     71 <p class="img-caption"><strong>Figure 1.</strong> Conceptual layout for an item in a {@link
     72 android.widget.ListView}.</p>
     73 
     74 <p>The {@code hierarchyviewer} tool is available in  {@code <sdk>/tools/}. When opened,
     75 the Hierarchy Viewer shows a list of available devices and its running components. Click
     76 <strong>Load View Hierarchy</strong> to view the layout hierarchy of the selected component. For
     77 example, figure 2 shows the layout for the list item illustrated by figure 1.</p>
     78 
     79 <div style="float:left;width:455px">
     80 <img src="{@docRoot}images/training/hierarchy-linearlayout.png" alt="" />
     81 <p class="img-caption"><strong>Figure 2.</strong> Layout hierarchy for the layout in figure 1,
     82 using nested instances of {@link android.widget.LinearLayout}.</p>
     83 </div>
     84 
     85 <div style="float:left;width:155px;margin-left:2em">
     86 <img src="{@docRoot}images/training/hierarchy-layouttimes.png" alt="" />
     87 <p class="img-caption"><strong>Figure 3.</strong> Clicking a hierarchy node shows its
     88 performance times.</p>
     89 </div>
     90 
     91 <p style="clear:left">In figure 2, you can see there is a 3-level hierarchy with some problems
     92 laying out the text items. Clicking on the items shows the time taken for each stage of the process
     93 (figure 3). It becomes clear which items are taking the longest to measure, layout, and render, and
     94 where you should spend time optimizing.</p>
     95 
     96 <p>The timings for rendering a complete list item using this layout are:</p>
     97 <ul>
     98   <li>Measure: 0.977ms</li>
     99   <li>Layout: 0.167ms</li>
    100   <li>Draw: 2.717ms</li>
    101 </ul>
    102 
    103 
    104 <h2 id="Revise">Revise Your Layout</h2>
    105 
    106 <p>Because the layout performance above slows down due to a nested {@link
    107 android.widget.LinearLayout}, the performance might improve by flattening the layout&mdash;make
    108 the layout shallow and wide, rather than narrow and deep. A {@link android.widget.RelativeLayout} as
    109 the root node allows for such layouts. So, when this design is converted to use {@link
    110 android.widget.RelativeLayout}, you can see that the layout becomes a 2-level hierarchy. Inspection
    111 of the new layout looks like this:</p>
    112 
    113 <img src="{@docRoot}images/training/hierarchy-relativelayout.png" alt="" />
    114 <p class="img-caption"><strong>Figure 4.</strong> Layout hierarchy for the layout in figure 1,
    115 using {@link android.widget.RelativeLayout}.</p>
    116 
    117 <p>Now rendering a list item takes:</p>
    118 <ul>
    119   <li>Measure: 0.598ms</li>
    120   <li>Layout: 0.110ms</li>
    121   <li>Draw: 2.146ms</li>
    122 </ul>
    123 
    124 <p>Might seem like a small improvement, but this time is multiplied several times because this
    125 layout is used for every item in a list.</p>
    126 
    127 <p>Most of this time difference is due to the use of {@code layout_weight} in the {@link
    128 android.widget.LinearLayout} design, which can slow down the speed of measurement. It is just one
    129 example of how each layout has appropriate uses and you should carefully consider whether using
    130 layout weight is necessary.</p>
    131 
    132 
    133 <h2 id="Lint">Use Lint</h2>
    134 
    135 <p>It is always good practice to run the <a href="{@docRoot}tools/help/lint.html">lint</a>
    136 tool on your layout files to search for possible view hierarchy optimizations. Lint has replaced
    137 the Layoutopt tool and has much greater functionality. Some examples of lint <a
    138 href="http://tools.android.com/tips/lint-checks">rules</a> are:</p>
    139 
    140 <ul>
    141 <li>Use compound drawables - A {@link android.widget.LinearLayout} which contains an {@link android.widget.ImageView} and a {@link android.widget.TextView} can be more efficiently handled as a compound drawable.</li>
    142 <li>Merge root frame - If a {@link android.widget.FrameLayout} is 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.</li>
    143 <li>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.</li>
    144 <li>Useless parent - A layout with children that has no siblings, is not a {@link android.widget.ScrollView} or 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.</li>
    145 <li>Deep layouts - Layouts with too much nesting are bad for performance. Consider using flatter layouts such as {@link android.widget.RelativeLayout} or {@link android.widget.GridLayout} to improve performance. The default maximum depth is 10.</li>
    146 </ul>
    147 
    148 <p>Another benefit of Lint is that it is integrated into Android Studio. Lint automatically runs
    149 whenever you compile your program. With Android Studio, you can also run lint inspections for a
    150 specific build variant, or for all build variants. </p>
    151 
    152 <p>You can also manage inspection profiles and configure inspections within Android Studio with the
    153 <strong>File&gt;Settings&gt;Project Settings</strong> option. The Inspection Configuration page
    154 appears with the supported inspections.</p>
    155 <p><img src="{@docRoot}images/tools/studio-inspections-config.png" alt="" /> </p>
    156 <p class="img-caption"><strong>Figure 5.</strong> Inspection Configuration</p>
    157 
    158 <p>Lint has the ability to automatically fix some issues, provide suggestions for others and jump
    159 directly to the offending code for review.</p>
    160 
    161 
    162 
    163 
    164 
    165 
    166 
    167