[MUSIC PLAYING]
COLT MCANLIS: And go.
[BEEP]
You know what this timer means?
Every quarter second a user spends
staring at a blank screen instead of interfacing
with your app is a quarter second more
they're willing to close your app
and give their attention to something else.
[BEEP]
My name is Colt McAnlis, and misunderstanding
all the complex things that happen during your app startup
can lead to some serious performance problems.
Now, see, Android is pretty smart
when it comes to understanding human performance perception.
As soon as the user launches your application,
Android will immediately display a start window, which
will stay around until your application is fully loaded,
initialized, and can draw its first frame.
This behavior is most often seen when
your app is booted for the first time,
but it can easily happen other times as well,
like when the activity is brought to the foreground,
or after the user backs out of your app,
or after some portion of your app
has been purged by the system to save memory.
Basically, any time the user moves from something else
to your application, there's a chance
you can see this type of behavior.
The important point here is this.
Letting the user spend too much time looking at the start
window gives them ample opportunity
to get bored and move on to other things.
And taking too long in general could even
cause the Application Not Responding dialog to pop up.
Neither of these are very good for user retention.
So from the technical side, the whole process
works something like this.
When the user launches your app, the system does a bit of work
to load your application information
and create a unique process for your app.
From there, the system process will
display the starting window and basically
hang out until the application is up and running.
Meanwhile, the application process
will create the application object
and launch the main thread.
This is where your startup activity
will be initialized, created, inflated, and finally drawn.
It's only at this point, after the application
has drawn its first frame, that the system process then
goes and swaps out the start window for the application.
Now, to be clear, the majority of that entire process
happens pretty cleanly.
There's not really much chance that performance
can go off the rails.
However, there are three big areas
where things could become problematic
that you should keep an eye on.
The first thing you should really take a look at
is all the work that goes into creating your activity class.
Most often, there's lots of heavy lifting
that occurs during this process, but heaviest
has to be the inflation of layouts and loading
of resources that goes along with it.
This is not a cheap process, and if your layouts are too complex
or you've got some blocking logic in there,
this can cause some really big problems.
On a similar note, make sure you take a look at your application
initialization.
For really complex apps, the initialization
of the app object often becomes a junk drawer
for lots of global classes that might
be used between activities.
So there tends to be lots of work here
that could be deferred to later times
or perhaps loaded in a lazy-load fashion.
Now, there's lots of applications out there
which provide custom start windows.
This is either done to help brand
the application or to make a slow load
look like a custom-branded application.
Now, if you're doing this to hide bad load times,
obviously, you should fix that first.
But if you're doing it for branding,
then you need to be aware that there's a right and a wrong way
to set this up, so that it doesn't influence the user
perception too negatively.
But before you run off into the weeds
and try to fix these types of common patterns,
you need to sit down and figure out
if you have a problem in the first place.
Thankfully, Android has a few tools to help.
Firstly is display time.
For releases after KitKat, Logcat
will include an output line which
displays the amount of time between when the process was
launched and the activity finally drawn to the screen.
This can be helpful, because it gives you
a general idea how long it takes to occur for your application.
Oh, by the way, note, if you want
to see this value inside of Android Studio,
you need to turn off filters for the Logcat output.
So keep that in mind.
Secondly is reportFullyDrawn function.
The displayed metric that's reported in Logcat
is useful for most situations where
you'd like to track down the time it
takes to go from application start to first visible.
However, in modern application development,
there's often a great deal of lazy loading-- that is,
rather than blocking the initial drawing of the window,
asynchronously loading resources and views in the background
and updating the view hierarchy accordingly.
The result is that while the initial activity may
be visible, it may not yet be fully loaded with respect
to resources, which could be considered
a separate metric to use when evaluating launch time
performance.
To address this concern, you can manually
call the activity.reportFullyDrawn
function to let the system know that your activity is finished
with its lazy loading.
Third is method tracing.
While display time and reportFullyDrawn
give a good understanding of the overall load
time of your application, they do not provide details
into what may be causing particular parts
of that pipeline to go longer than expected.
To gain more insight in this area,
you can use the start method tracing
tool inside of Android Studio.
And finally is the big one, Systrace.
When you add trace functions inside
of your onCreate methods, it will augment your logging,
such that the Systrace tool can properly
discover all the subsections and display them
in its graphing process.
And if you're looking for more great performance insight,
don't forget to check out the rest of the "Android
Performance Patterns" content.
And be sure to join the Google+ community to ask questions from
other perf gurus.
So keep calm, profile your code, and always remember,
perf matters.
[MUSIC PLAYING]