How do you approach a performance problem, and which kinds of problem are there?

21.1.1 · L2 · Interview

Predict first

You tune a screen and it “feels faster”. What is the correct next step?

// A: ship it, the feel is the metric
// B: re-run the same scenario and the same metric you started with, and compare
// C: profile again after changing three more things
  • A
  • B
  • C

Mental model. A doctor does not operate because you say “it hurts”. They take a measurement, find the cause, treat one thing, and check the measurement again.

Work in a loop and do not skip steps: 1) reproduce the problem on a stable scenario (a script, a UI test, a fixed data set), 2) pick one metric that defines “slow” (launch to first frame, p95 scroll hitch rate, peak memory, bytes written, battery percent per hour), 3) profile to find where the time or resource goes instead of guessing, 4) change one thing, and 5) measure again under the same conditions. If the number did not move, the change was not the cause, whatever your instinct said. Keep the baseline so a later regression is visible, and stop when you hit the target, because every optimisation adds code that someone must maintain.

It also helps to know which kind of problem you have, because each kind has its own metric and its own tool. A launch problem is time to first usable frame. A hang is a blocked main thread (the app ignores input); a hitch is a missed frame deadline while scrolling or animating, and Q287 explains the difference. A memory problem is footprint and peak, which ends in a jetsam kill rather than a slow screen (Q162). Disk is bytes written and I/O wait, battery is energy over time, and binary size is the download and install cost. Start from the symptom the user sees, map it to the metric, then open the matching instrument.

A change is only an improvement if the agreed number moved under the same conditions; feeling is not evidence.

Typical metricFirst tool
Launchtime to first usable frame, p50 and p90App Launch instrument, MetricKit launch histograms
Hangmain-thread blockage over about 250 msHangs instrument, Time Profiler
Hitchhitch time ratio while scrollingAnimation Hitches instrument
Memorypeak and steady footprint, jetsam killsAllocations, VM Tracker, memory graph
Diskbytes written per day, I/O waitFile Activity, MetricKit disk-write diagnostics
Batteryenergy per hour of usePower Profiler, Energy gauge, Organizer
Binary sizedownload and install sizeApp Thinning size report, link map

Common traps

  • Optimising on a hunch. Most of the time is in a place nobody guessed; profile first.
  • Changing several things at once. You cannot tell which one helped, or which one hurt.

They might follow up with

  • When do you stop? When the metric meets the target, or the next gain costs more complexity than it is worth.
  • What do you do if the profile shows nothing obvious? Look at a different dimension (wall time versus CPU time, main thread versus others, I/O or waiting) before deciding the app is “just slow”.

Related questions

  • 21.1.2 How do you measure performance reliably: what makes numbers lie, and why do percentiles beat averages?
  • 21.2.1 Which Instruments templates do you reach for, how do you read a Time Profiler trace, and where can a sampling…
  • 9.7.1 What is a hitch versus a hang, how does ProMotion change the budget, and how do you measure and fix them?
  • 3.7.5 What is memory footprint, and what gets an iOS app killed?
  • 6.4.3 Your app launches slowly. How do you find out why and what do you cut?

How do you measure performance reliably: what makes numbers lie, and… →