diff --git a/docs/html/images/training/app/madscientist.png b/docs/html/images/training/app/madscientist.png new file mode 100644 index 0000000000000..5e670568357a8 Binary files /dev/null and b/docs/html/images/training/app/madscientist.png differ diff --git a/docs/html/jd_collections.js b/docs/html/jd_collections.js index 9f39602f61d03..59b4efa191186 100644 --- a/docs/html/jd_collections.js +++ b/docs/html/jd_collections.js @@ -1670,4 +1670,12 @@ var RESOURCE_COLLECTIONS = { "training/testing/performance.html" ] }, + "app/landing/videos": { + "title": "", + "resources": [ + "https://www.youtube.com/watch?v=CaMTIgxCSqU", + "https://www.youtube.com/watch?v=OrLEoIsMIAc", + "https://www.youtube.com/watch?v=bSOREVMEFnM" + ] + }, } diff --git a/docs/html/training/app/approach.jd b/docs/html/training/app/approach.jd new file mode 100644 index 0000000000000..3177fb3437389 --- /dev/null +++ b/docs/html/training/app/approach.jd @@ -0,0 +1,175 @@ +page.title=Gather, Insight, Action +meta.tags="android, performance", "app" +page.tags="app" +page.article=true +@jd:body + + + + + +
Your app has a performance problem if it does not instantly respond +to a user action, stutters, or makes the user wait at any point. +This lesson introduces the most basic performance test for your app, +and a process for iteratively finding and fixing performance problems.
+ + +To find out whether your app has performance issues, you don't need fancy + tools.
+ +Do the following:
+ +If these hands-on tests didn't reveal any performance problems,
+ +If you gathered any notes related to performance, then performance is a problem for your + app.
+ +Once you have subjectively established that your app could benefit from performance tuning, we + have two recommendations for an objective and systematic approach to finding and fixing + performance problems faster.
+ + + +Android and Android Studio come with many + + performance profiling tools + to help you + identify performance problems and track down where they are in your code. And after you have + changed your code, run the tools again to measure the impact of your change. Compare results to + make sure you've fixed the right problem, and find out whether you need to + make additional performance improvements.
+ +To learn more about why you should use tools, see + Tools Not Rules.
+ + + +When optimizing your application, you must be able to measure its state, make changes, and + then evaluate the performance differences of these changes. Thus, the Performance Tuning + Lifecycle is built around the concept of "What you can measure, you can + optimize".
+ +The Performance Tuning Lifecycle (Figure 1), consists of three phases: + gather information, gain insight, and take action.
+ +
+ + Figure 1. The Performance Tuning Lifecycle. +
+
+
+ Gather Information.
+ Use the
+
+ performance profiling tools
+ to capture data
+ about your app. Since most tools are specialized, you may need to run several tools.
+
+ Gain Insight.
+ Take the time to understand what your gathered data means for your app.
+ You may need to go through several iterations of gathering information and gaining insight to
+ pinpoint what the problem (or problems!) is.
+
+ Take Action.
+ Take all the information and all the insights, and determine and evaluate
+ different ways to solve your problem. Taking action can take different forms, and what you decide
+ to do depends on your situation and context, which may also include coding resources, budgets,
+ and deadlines.
And once you've taken action, verify that your changes had the desired + outcome:
+ +
+
+ Gather a second set of data.
+
+ Compare it to your original data.
+
+ Make more changes...
+ and repeat this process until your app consistently responds smoothly to all user actions, never
+ stutters, and never makes the user wait. On all target devices.
To learn more, see + The Performance Tuning Lifecycle.
+ + + + + + +
+ + Everything you need to know about improving your app’s performance.
+ + + + Test you app's performance +This series of lessons teaches you how to improve the performance of your + Android applications using a workflow of gathering data, analyzing the data, and + taking action based on your insights.
At the heart of your app is the hierarchy of views that makes up the user interface and the + visual experience of users. With feature-rich apps, this hierarchy grows large and complex and + can become a source of performance problems. The most likely symptom you will see is a generic + general slowness of the app, especially when rendering complex views to the screen.
+ +Simplifying or rearranging the view hierarchy of your app can improve performance, especially + on lower-end devices and earlier versions of Android. As an added benefit, your app will become + easier to maintain overall.
+ +Analyzing the view hierarchy is an example of using several tools together to pinpoint and fix + performance problems. It is also an example of eliminating another inefficiency first, so that + your data becomes more precise.
+ + +If you have not done so already, reduce overdraw by removing unnecessary backgrounds. This + will remove a common source of overdraw that is not related to your view hierarchy. See + + Visualizing and Reducing Overdraw.
+ +Hierarchy Viewer can help identify these specific issues that are directly related to the + structure of the view hierarchy.
+ +Minimizing these issues can improve performance, especially on older devices. For your own + benefit, these simplifications will make your code easier to maintain and profile in the + future.
+ +Remove views that do not contribute to the final image.
+ +
To identify views that do not contribute to the final image on the screen:
+ +
+ + Figure 1. Views 2 and 3 are fully obscured and can be safely removed. +
+Eliminate from your code the views that are completely covered, never displayed, or outside + the screen.
+ +Simplify nested layouts that trigger multiple layout passes.
+ +Some layout containers, such a RelativeLayout, require two layout passes in order to finalize + the positions of their child views. As a result, their children also require two layout passes. + When you nest these types of layout containers, the number of layout passes increases + exponentially with each level of the hierarchy.
+ +For example, a view inside a grid view inside a list view inside a relative layout could get + laid out 8 times(!) as shown in Figure 2.
+ +
+ + Figure 2. Example of layout pass multiplication. +
+Watch out for the following containers and conditions:
+ +measureWithLargestChild layout weightUsing any of these containers as
+ +can result in noticeable performance penalties.
+ +For more information, see + Double Layout Taxation.
+ + + + +Consider whether you can achieve the same layout using a container configuration that does not + result in these exponential numbers of layout passes. For example:
+ +In addition, you can apply all the techniques mentioned in this document to simplify the view + hierarchy.
+ +For more tips, see + + Optimizing Layout Hierarchies.
+ + + +If your user interface has many simple views, you may be able to combine some of them without + diminishing the user experience, as shown in Figure 3.
+ + +
+ + Figure 3. Example of combining views. +
+Both the changes below may affect how you present information to the user and will include + design trade-offs. Remember that performance is more important than anything else for your + app's success, and opt for simplicity wherever you can.
+ +Does your view hierarchy have parts that look like the nested arrangement on the left of + Figure 4?
+ +
+ + Figure 4. This deep view hierarchy can be flattened to improve performance. +
+Flatten the view hierarchy by replacing nested linear layouts with relative layouts wherever + possible. See + + Optimizing Layout Hierarchies.
+ + + +Watch a screencast which shows how to apply all these techniques to simplify a view + hierarchy. See + + Optimizing Layouts with Hierarchy Viewer.
+ +Use the + Lint tool + on your layout files to search for possible view hierarchy optimizations. See + + Optimizing Layout Hierarchies: Use Lint.
+ diff --git a/docs/html/training/app/rendering/index.jd b/docs/html/training/app/rendering/index.jd index 733131e0aff15..19d274b8af9a4 100644 --- a/docs/html/training/app/rendering/index.jd +++ b/docs/html/training/app/rendering/index.jd @@ -1,4 +1,92 @@ -page.title=Optimizing Rendering Performance +page.title=Rendering Performance page.tags=render - +page.article=true @jd:body + +The most common performance problems are related to how your app draws, and how that + eventually appears on the user's screen.
+ +Finding rendering problems is an iterative process of using hands-on testing to + identify problem spots, harness tools to discover the underlying cause, and improve your code. + See also + Test Your App's Performance.
+ +Optimizing rendering performance means to remove unnecessary work, simplify structures + and processes, manage bitmaps properly, and be mindful of the natural constraints imposed by the + hardware and the Android system.
+ +The result of great rendering performance is instantly INVISIBLE to your users. That + is, your app runs so fast and smoothly, that users fully focus on their task, not on your + app's UI and performance.
+ +You can test for and improve common rendering problems by using the tools and strategies + recommended in this course.
+ +Every time your app draws a pixel on the screen, it takes time. Every time your app draws a + pixel that has already been drawn, it wastes time. Drawing a pixel more than once per screen + refresh is called overdraw, and it's a common problem affecting + the performance of modern applications. To be efficient, every time your app refreshes the + screen, it should draw every changed pixel only once.
+ +For example, an app might draw a stack of 52 overlapping cards, with only the last card fully + visible. Completely drawing the 51 cards that are underneath and partially covered, is an example + of overdraw.
+ +
+ + Figure 1. Example of card stack with potential overdraw. +
+Watch the + Understanding Overdraw + video + for a detailed introduction, and see the rest of this page for more on finding and fixing + overdraw.
+ + + +Note: Reducing overdraw can save significant GPU resources and greatly + decrease the time it takes to draw a frame. Reducing overdraw may have a significant impact, if it + is the biggest performance issue your app has; or it may have no noticeable impact, if you are on + a fast device, or if your app has other, much bigger performance issues.
+ + +You can visualize overdraw using color tinting on your device with the + Debug GPU Overdraw tool. +
+ +To turn on Debug GPU Overdraw on your mobile device:
+ +See + Debug GPU Overdraw + for a full tutorial, or try the Debug + GPU Overdraw Codelab.
+ + +As a general rule, if at any given point your app is drawing something that the user does not + see, don't draw it. More specifically, Debug GPU Overdraw highlights can guide + you to the following issues:
+ +Search your code for android:background, and for each
+ background, determine whether it's needed and visible on the screen.
Removing unnecessary backgrounds is a quick way of improving rendering performance. An + unnecessary background may never visible, because it's completely covered by + everything else the app is drawing in that view. For example, a parent's default + background that is overdrawn by the children's custom backgrounds.
+ +You can remove backgrounds by removing the android:background? line of code in an view.
Before:
+ ++ <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/activity_chatum_latinum_container" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@android:color/white" <===== Background + tools:context=".MainActivity" + tools:ignore="MergeRootFrame" /> ++ +
After:
+ ++ <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/activity_chatum_latinum_container" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".MainActivity" + tools:ignore="MergeRootFrame" /> ++ + +
Find areas that are drawn unnecessarily and clip generously.
+ +When you are using custom views, you may be redrawing areas of the screen that have not + changed.
+ +For each update, even if only a portion of a custom view has changed, the entire view must be + rebuilt. This is most common for views that use Canvas for drawing. For example, if you draw a + small circle in a corner of the view, the whole view gets rebuilt.
+ +The Android system does to a good job at culling views that are 100% invisible or overlapped + by another view, but cannot eliminate more complex views, for example those that include + text transparency or rounded corners.
+ +Before you draw a custom view, test whether it's visible at all. If it is + visible, only draw the portions that the user sees.
+ +See + Overdraw, ClipRect, QuickReject.
+ + diff --git a/docs/html/training/app/rendering/profile-gpu.jd b/docs/html/training/app/rendering/profile-gpu.jd new file mode 100644 index 0000000000000..56a65fb5fefe5 --- /dev/null +++ b/docs/html/training/app/rendering/profile-gpu.jd @@ -0,0 +1,356 @@ +page.title=Improve GPU Rendering Performance +meta.tags="android, performance", "app" +page.tags="app" +page.article=true +@jd:body + + + + +The most common issues that can make your app slow are related to the process of drawing on + the screen. Android provides the + Profile GPU Rendering + tool on your + device to analyze the rendering performance of your app. The Profile GPU Rendering tool draws a + graph on the screen to show the rendering performance of each window.
+ +This page introduces how to use the Profile GPU Rendering tool and interpret its graphs, and, + depending on your findings, suggests what to try next to optimize your app's + performance.
+ +For a quick overview of the tool and how to use it, watch the embedded + Profile GPU Rendering video. + Then profile your app and analyze the results following the steps + below.
+ + + + + +Turn on Profile GPU Rendering:
+ +You are going to see a chart of multi-colored bars on your screen, similar to Figure 1. Each + vertical bar represents one frame of rendering for that activity, that is, one redrawing of the + window on the screen.
+ +
+ + Figure 1. Profile GPU Rendering graph. +
+The height and coloring of a bar, as shown in Figure 1, indicate how fast each frame was + created, and how much time different phases of the rendering process required.
+ +The green line marks 16 milliseconds. If a bar crosses that line, it took more than 16 + milliseconds to create and draw that window on the screen. If this happens often, or if any bars + cross the line by a lot, users can probably notice a delay or stutter while using the app.
+ + + +Look at the colored segments of the bars that cross the green 16 millisecond line, in + particular any segments that are much taller than their neighbors.
+ +If you see that
+ +To improve the performance of your app, you may need to take one, some, or all of the actions + on this page. You may need to use more additional tools or investigate other sources of performance + issues.
+ +For example:
+ +The blue Update segment of the bar represents the time used by the CPU to create and update + all the views for this rendering of the screen. This is part of a processing sequence called the + invalidation pipeline. To learn more about the invalidation pipeline, see + Views, Invalidations, and Performance + and Double Layout Taxation.
+ + + + + +If this blue bar segment is tall, it can indicate that your app does too much work creating + and updating views, or is updating too many views or views that are too complex.
+ +Reduce overdraw.
+ +Simplify complex view hierarchies.
+ +Optimize onDraw() for custom views.
+ +The purple segment of the bar represents the time the GPU Driver spent transferring resources + from the CPU to the GPU. Moving a significant amount of data between processors takes time, and + the larger the data to be moved, the longer the delay in execution. + See CPU, GPU, and your Android.
+ + + + +The red segment of the bar represents the time spent by Android's 2D renderer issuing commands + to OpenGL to draw and redraw display lists. The height of the red bar is proportional to how much + time was spent submitting commands to the GPU for the total of all views that need to be redrawn. + Display lists that do more complex operations contribute more time to the overall size of the red + bar. The size of the red bar is an indicator of the complexity of the display + lists' operations. The number of display lists does not directly + correlate to the size of the red bar.
+ +Reduce overdraw.
+ +Limit alpha blending.
+ +The orange segment of the bar represents the length of time that the CPU is waiting for the + GPU to finish its work. After transferring data to the GPU, the CPU waits for the GPU to + acknowledge receipt. If this bar segment gets tall, it means the app is doing too much complex + work on the GPU, and the GPU is unable to keep up with the data flow from the CPU.
+ +Simplify complex view hierarchies.
+ +Optimize drawing.
+ +The following checklist summarizes common rendering problems and solutions. +For each problem, learn how users are affected, how to diagnose, and how to +approach fixing it. Use the linked resources for details on the suggested solutions.
+ + + +What the user sees:
+ The most likely symptom is a generic general slowness of screen
+ rendering, as well as stuttering animations.
Use this tool:
+
+ Debug GPU Overdraw
What you see:
+ Red-colored views indicate multiple layers of unnecessary drawing.
Problem:
+ Your app redraws the same pixels multiple times, resulting in
+ overdraw.
Solution:
+ If you are drawing pixels on the screen that the user never sees, you might
+ be able to improve drawing performance by removing unnecessary backgrounds, reorganizing views,
+ and applying clipping techniques to custom views.
Optimize your app:
+ Reduce Overdraw,
+ Simplifying View Hierarchies,
+ and
+ Apply Clipping.
What the user sees:
+ The most likely symptom is a generic general slowness of the app,
+ especially when rendering complex views to the screen.
Use this tool:
+ Hierarchy Viewer
What you see:
+ A view hierarchy that is deeper than wide, with a lot of nesting. When
+ you profile your view hierarchy, there are red dots in leaf nodes.
+ See
+ Profiling with Hierarchy Viewer.
Problem:
+ The more complex and deep your view hierarchy, the more likely it is that a
+ simple change to a view can trigger multiple passes through large parts of this hierarchy to
+ recalculate the sizes, positions, and layout of affected views.
Solution:
+ Flatten and simplify your view hierarchies. Try different layouts. Combine
+ views.
Optimize your app:
+
+ Simplify Complex View Hierarchies.
Use these tools:
+ On your mobile device, in Developer Options, turn on
+ Profile GPU Rendering
+ and GPU View Updates.
What you see:
+ In Profile GPU Rendering, for bars that cross the 16 millisecond threshold, the
+ blue updated segment in particular may be large. The M release of Android adds additional color
+ segments, and the Measure/Layout segment may also be larger than expected.
In GPU View Updates, portions of the screen will flicker wildly in response to user + actions:
+ +Every time a view changes, the display lists are invalidated and have to be + recreated and executed.
+ + Solution:While it is impossible to avoid invalidations, minimizing how often they + happen, and how many views are affected, can improve your app's + performance.
+ + Optimize your app:Minimize view invalidations. See + Views, Invalidations, and + Performance + and Double Layout Taxation.
+ + + + +What the user sees:
+ Slow response to user-initiated actions. Sluggish scrolling.
Use these tools:
+ Hierarchy Viewer.
+ On your mobile device, in Developer
+ Options, turn on
+ Profile GPU Rendering
+ and GPU View Updates.
What you see:
+ In Profile GPU Rendering, for bars that cross the 16 millisecond threshold, the
+ blue segment in particular may be large. In GPU View Updates, large portions of the whole screen
+ will flicker wildly in response to user actions. In Hierarchy Viewer, look for red dots in the
+ measure and layout phases, especially on leaf nodes.
Problem:
+ Changing the position or size of a view can trigger a cascade of calculations
+ throughout your view hierarchy to adjust neighboring and parent views.
Solution
+ You might be able to improve rendering performance by rearranging or
+ simplifying your view hierarchy, or by using different layout containers.
Optimize your app:
+
What the user sees:
+ App slows down whenever views and animations use alpha
+ rendering.
Use this tool:
+ Profile GPU Rendering.
+ Also, in Developer options, turn on
+ Show Hardware Layers Updates. The screen will flash green for every hardware layer update. Note
+ that for pre-M (API level 22 and below), you have to use hardware layers explicitly (e.g.
+ mView.animate().alpha(0).withLayer().start()), while for API levels 23 and above, the system does
+ this for you automatically.
What you see:
+ In the Profile GPU Rendering graph, orange bar segments may be tall,
+ because the CPU is waiting for the GPU to finish all this work. On our device, the screen will
+ flash green while your app slows down. See
+
+ Optimizing Hardware Layers for an example.
Problem:
+ From a performance perspective, fade and transparency effects are expensive,
+ because you have to draw every pixel and possibly whole parts of your view hierarchy multiple
+ times.
Solution:
+ You might be able to improve drawing performance by controlling how the
+ renderer uses hardware layers and by using alpha rendering sparingly.
Optimize your app:
+ Eliminate non-critical alpha rendering and use hardware layers
+ effectively. Learn more on The Hidden Cost of Transparency
+ and
+ Hardware Acceleration
What the user sees:
+ Intermittent drops in frame rate, and crashes in the worst
+ case.
Use these tools:
+ Memory Monitor
+ and Heap Viewer.
What you see:
+ In Heap Viewer, look for large bitmap
+ objects. In Memory Monitor, you'll see an unhealthy number of garbage
+ collection events.
Problem:
+ Once loaded, your app's bitmaps are uncompressed, which
+ not only uses up memory but also affects garbage collection.
Solution:
+ You might be able to increase available memory, reduce garbage collection
+ overhead, and increase rendering performance by using smaller bitmap pixel formats.
Optimize your app:
+ Consider Smaller Pixel Formats. See Smaller Pixel Formats.
What the user sees:
+ Intermittent drops in frame rate, and crashes in the worst
+ case.
Use these tools:
+ Memory Monitor
+ and Heap Viewer.
What you see:
+ In Heap Viewer, look for large bitmap objects. In Memory Monitor,
+ you'll see and unhealthy number of garbage collection events.
Problem:
+ If the bitmaps your app is loading are larger than what is being displayed on
+ the screen, they unnecessarily use memory space.
Solution:
+ You might be able to increase available memory and rendering performance be
+ pre-scaling your bitmaps.
Optimize your app:
+ Use Pre-scaled Bitmaps.
What the user sees:
+ Intermittent drops in frame rate, and crashes in the worst
+ case.
Use these tools:
+ Memory Monitor
+ and
+ Allocation Tracker.
What you see:
+ In Allocation Tracker, look for bitmap objects. In Memory Monitor, you
+ may see an unhealthy number of garbage collection events.
Problem:
+ Your app is loading a stream of bitmaps that are each only used for a short
+ time.
Solution:
+ You might be able to improve memory usage and rendering performance by using
+ object pools to reuse existing bitmap objects, and be reusing and caching bitmaps and
+ textures.
Optimize your app:
+ Reuse Bitmaps
+ and consider using Object Pools.
+ Consider using the Glide Library.
+
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index 04af2df344c30..36a400e2a9a09 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -1848,10 +1848,11 @@ results."