Having worked on performance for different kinds of products over the years, I thought I'd write up a post reflecting on some differences in approach when thinking about "classic apps" and "games/realtime-y experiences".
The stuff in common
When tuning performance for user experiences, there is quite a bit of overlap. For example, many of the metrics that matter for one will matter for the other.
- Latency. Humans have their own expectations, regardless of how we've architected our software. Users will expect low latency in general, otherwise they might think the system is not responsive or grow frustrated or being losing focus and break flow.
- There are typically two points of latency that matter. The first one is the 'stricter' one, which is the point at which the user receives feedback that the system has received their request. This could be a press/depress effect on a button, a sound or audio cue, or haptic feedback. The second depends a bit more on the workload and is effectively how long it takes to do the thing the user asked for.
- Framerate. Again, the visual system doesn't care about how we've built software. To achieve the illusion of movement, we'll need to update things at a high framerate.
- Startup time. This is in many ways a special case of latency, but generally the "forces" at play are different, and so we usually work on this separately. Typically you'll be contending with loading things from disk or the network, setting up new connections to other systems on the device, rehydrating state, etc.
- Shared resource utilization. How much memory, network bandwidth, CPU cycles, battery power, etc. are all things we care for any experience we build.
The basic approach, works for both of these, like so many other systems.
- Identify key scenarios.
- Identify workloads.
- Set performance goals.
- Define budget.
- Model process.
- Allocate budget.
- Measure.
- Monitor.
Iterate by revisiting scenarios, workloads and goals as the project progresss.
Make improvements to the process and implementations, then adjust how you allocate your budgets and measure, and setup systems to monitor.
Approach for apps
There are characteristics of this class of apps that we can see again and again.
- Classic event-driven apps like Android UI, UIKit or Windows (classic HWND or XAML-style).
- On-demand spiky workloads, typically in response to user gestures. Because these are not often presented with continuous feedback, there is a bit more tolerance for pauses.
- "Not doing anything" by default. Most of the time, these apps should be sitting idle, waiting for user interaction.
- Timers and background tasks are often how non-user-interaction activity is initiated. These can keep the device busier than it should be.
- Managing latency for long-running operations is often a matter of showing progress or allowing the user to continue making progress without blocking them.
- Managing latency for resumption and app switching is often a concern, as users have high expectations here.
- Frame rate matters but is only a concern during animations and transitions (although there are some special cases I call out before).
- Battery life matters quite a bit. We don't want to drain things.
- Keeping resource usage low to improve the chances of being kept around and having fast resumption.
- There is plenty of support from common tools, like Perfetto timelines and jank detection on Android UI or WPA profile on Windows.
There are also workloads that will often stress the platform a bit more, and have special paths for them.
- Video playback and camera are common workloads.
- Heavy processing, either for media (transcoding, mixing) or by complexity (number crunching).
- Machine learning or other workloads where specialized hardware might be leveraged.
Approach for games
Games frequently present a different workload. Turn-based games might sometimes sit somewhere in the middle, but for continuous experiences these are good points.
- Continuous workload like a game loop that updates regularly.
- Constant load and dealing with spikes are important concerns.
- Frame rate is a constant worry, smoothness is easy to notice and jarring.
- Memory might matter less if it's more of a dedicated workload.
- CPU matters quite a bit, scheduling things efficiently is important.
- Thermals from constantly running, don't want to get throttled. That said, users often have different expectations for battery impact.
- Perfetto timelines are also used, but game engine internals need to be considered.
Happy perf tuning!
Resources
Tags:
android perf
Home