Diagnoses and fixes mobile jank, dropped frames, slow startup, and growing memory by capturing a trace or heap snapshot on a real device, isolating the single worst cost, fixing it, and re-measuring against the 16ms frame and cold-start budgets. Use when someone says "the app stutters when I scroll", "startup takes forever", "memory keeps climbing after navigating around", or the UI feels laggy on a real device. Do NOT use when the bottleneck is a website or web app (LCP, bundle size, slow endpoint or query) - use web-performance instead; for Compose recomposition fixes pair with jetpack-compose-builder; for Flutter widget architecture use flutter-widget-architect.
Click to play with sound.
---
name: Mobile Perf Profiler
description: Diagnoses and fixes mobile jank, dropped frames, slow startup, and growing memory by capturing a trace or heap snapshot on a real device, isolating the single worst cost, fixing it, and re-measuring against the 16ms frame and cold-start budgets. Use when someone says "the app stutters when I scroll", "startup takes forever", "memory keeps climbing after navigating around", or the UI feels laggy on a real device. Do NOT use when the bottleneck is a website or web app (LCP, bundle size, slow endpoint or query) - use web-performance instead; for Compose recomposition fixes pair with jetpack-compose-builder; for Flutter widget architecture use flutter-widget-architect.
---
# Mobile Perf Profiler
Diagnose mobile performance from measured evidence, fix the largest cost, and re-measure - never guess. The costly failure is folklore optimization: weeks spent caching and micro-tuning paths the profiler would show are cheap, while the one 40ms bind on the scroll path ships untouched.
## Operating procedure
### Step 1: Gather inputs
1. The exact symptom, named precisely: jank while scrolling a specific list, jank on first frame of a screen, slow cold start, or memory that climbs. "The app feels slow" is not a symptom yet - reproduce until it is one.
2. A representative device: a real mid-tier phone from the install base, not the developer's flagship and never a simulator/emulator.
3. A release or profile build. Debug builds misreport timing by integer factors.
4. The display refresh rate of target devices - 60Hz means a 16.6ms frame budget, 120Hz means 8.3ms.
5. Field data access: Play Console Android vitals, Xcode Organizer / MetricKit. If available, this decides which symptom is worth the trace before any local work.
### Step 2: Work the evidence ladder, cheapest first
Escalate only when the cheaper rung has not localized the cause:
1. Field data (minutes, zero setup): Android vitals and Xcode Organizer already know the slow-frame rate, frozen-frame rate, cold-start percentiles, and which devices are worst. Confirm the reported symptom exists at scale and pick the worst screen/device class.
2. On-device overlays (seconds to enable): Android GPU rendering profile bars, Flutter performance overlay. Watch the bars while reproducing - this tells which screen and roughly which frames blow the budget.
3. Trace capture (minutes per run): iOS Instruments - Time Profiler (CPU), Animation Hitches (rendering); Android Perfetto/system tracing; Flutter DevTools timeline reading the UI-thread vs raster-thread split. This names the expensive function or phase.