[MUSIC PLAYING]
BEN WEISS: In this MAD Skills video,
we'll recover important performance metrics, data
that helps you understand how an app is performing
and where you should spend time and effort to improve it.
App startup and creating a smooth user experience
have shown to have a lasting impact
on user satisfaction and your app's individual business
metrics.
We have tools and libraries lined up
to make it easier for you to inspect, improve, and monitor
performance.
Application startup are the first point
of interaction with your user, and making a lasting, positive
first impression is even more important at scale.
So your goal is to make the app startup as fast,
seamless, and smooth as possible.
I'll show you what to look out for.
Let's get started.
App startup can be measured in three stages--
cold start, warm start, and hot start.
The startup type is determined by the point
at which your app starts.
A cold start begins when the application's process
is created.
This is what users experience when they install your app
and launch it for the first time,
launch the app after restarting the device,
or restart the app after the system has completely stopped
it for one reason or another.
During a cold start, the Application#onCreate() method
is called.
Everything your app needs to get started is loaded from disk.
When a cold start begins, memory caches are empty as well.
Cold starts are the slowest startup phase.
You can easily experience a cold start of your app
by force closing it and then opening it again
from the launcher.
When a cold start takes longer than 500 milliseconds,
your users are going to notice and might
get increasingly impatient, especially on high-end devices.
So keeping cold starts as fast as possible
is extremely important.
The next startup type is called a warm start.
A warm start is measured from the point where
Activity#onCreate() is called, just before your view hierarchy
is inflated.
At this point, some resources, such as strings
and the first image resources, could already be inflated
and memory caches already warmed up.
Warm starts usually take place when
you open an app after the activity was destroyed,
but the app's process is still running.
This could happen if an app is running
in the background for a while but not long
enough for the system to kill the entire process.
Also, whenever an orientation change
forces the activity to be destroyed and recreated,
that's a warm start.
The final and shortest app startup type
is called a hot start.
During a hot start, an app becomes visible to the user
and enters the started state.
Here, the first frame is ready to be drawn,
and Activity#onStart() is called.
A hot start happens when the app was briefly in the background
and is being moved to the foreground again,
like when you're switching back and forth between apps.
Due to the nature of startup types,
a cold start takes the most time.
Warm starts and hot starts will be shorter.
All three startup types-- cold, warm, and hot--
are measured from the corresponding start points
to at least one of two end states.
The default app startup end state
is called Time To Initial Display, or TTID for short.
It is automatically reported when
the first frame of your application
is ready to be drawn.
You can see TTID by opening logcat and looking
at the ActivityTaskManager tag.
It will tell you how much time it took
to display a specific activity.
Because this is reported automatically,
there's nothing for you to configure.
Every app is reporting this by default. But being developers,
you probably like APIs that enable
you to customize the behavior.
Well, I have good news for you.
While time to initial display is reported automatically,
the next state can be customized.
It is called Time To Full Display, or TTFD.
TTFD is an optional metric that Android
can use to further optimize your app startup time.
It can also be used when you are running
startup benchmarks on your app.
TTFD is also visible in logcat.
You should report time to full display
when everything is drawn on screen
and the data required for the user to interact with the app
is available.
The API to use is Activities#reportFullyDrawn().
ReportFullyDrawn() is not tied to an activity lifecycle
method, and you must pick the right time to call the API that
makes sense for your app.
And while it is important to call a reportFullyDrawn()
around the time your app is ready to be used,
being absolutely precise on a frame level is not required.
The Now in Android sample app is considered
to be fully drawn when both the interests and feed have
been loaded.
Once these two states are met, we call the reportFullyDrawn()
when the current local view is ready to be drawn.
You can check out the code in more detail on GitHub.
Now you know about app startup phases,
when time to initial display is reported,
and when to report time to full display.
Aiming for less than 500 milliseconds to start
can be challenging for some apps.
In the upcoming videos, we're talking
about how tools, libraries, and best practices
can help you achieve this.
Now, let's talk about what to pay attention
to when aiming to make the overall app
experience smoother.
Have you experienced slower, choppy scrolling?
Well, it's not a fun thing to watch, and experiencing it
can range from being mildly annoying to being exceptionally
frustrating.
We call this behavior jank.
Jank happens when your app is too busy doing work
on the main thread and misses the timing window
to draw a frame on screen.
Jank can happen when scrolling but also
any other time content is moved on screen,
such as when animating between scenes
or transitioning from one window to another.
To avoid jank, you need to know what to look out for.
The screen can be drawn many times per second.
The amount of redraws per second is called frame rate.
Traditionally, Android devices came with a frame rate
of 60 frames per second.
That gives you 1/60 of a second to perform work
on the main thread before a frame will be delayed
or eventually has to be dropped.
But in recent years, the frame rates
have increased to 90 or even 120 frames per second,
and devices can also switch between different frame rates
depending on the user's choice, developer's decision,
or even the device's power or thermal state.
Within our modern Android development guides,
we recommend you optimize for a framework of at least 90 frames
a second.
This means that all the work in between frames
has to fit in a window of less than 11.1 milliseconds,
and that is very, very little time.
The best way to achieve this is by keeping as much work as
possible off the main thread.
I'll leave you with important general guidance
on measuring performance data.
Always measure release builds.
Release builds are what your users see
when they start using your app.
A release build has optimizations
enabled that improve app performance drastically.
The Resource Shrinker reduces the time
it takes to load images and other resources.
With Minification enabled, the compiler
makes your code more performant, reducing the time
it takes to execute work.
Startup and runtime performance vary depending on the device
it is run on and how busy the system
is at the time of measuring.
So while startup might be slow on a low-end device,
it can look just fine on a current flagship.
And while not everyone has access
to a wide variety of devices, we recommend
you test on a real device which is representative
of your users.
The Android emulator has come a long way,
and it's incredibly useful when developing an app,
but the host system running the emulator
can have very different performance characteristics
than the device that might run your app.
So always measure performance on a real device.
Finally, measure twice, improve once.
Make sure to gather metrics more than once
before attempting to optimize.
Code does not always execute at the same exact pace,
even when running on the same device,
depending on many factors.
So by taking multiple measurements,
your margin for error shrinks, and it's more likely
that optimizations have the effect that you are hoping for.
In the next video, Thomas will go in depth on inspection.
He will take you through best practices and libraries
that help you collect valid and consistent performance metrics.
All links to content I've mentioned in this video
are in the description.
Let us know what you thought of this video in the comments
below.
And if you'd like to see more content like this,
click the thumbs up and subscribe to the Android
Developers channel.
Thanks for watching.
See you next time.
[MUSIC PLAYING]