Розробник каже: «додаток гальмує при переході між екранами». Це — не дані для роботи. Профілювання CPU мобільного додатку за допомогою Instruments та Android Profiler дає точні дані замість здогадок. Кожен другий проект, який потрапляє до нас на аудит, має проблеми з продуктивністю CPU на головному потоці. В середньому знаходимо 5–7 вузьких місць на 1000 рядків коду. Типова картина: 80% часу витрачається на 20% методів — закон Парето в дії. Без профілювання знайти ці 20% практично неможливо. Дані — це «перехід з HomeViewController на DetailViewController займає 380 мс, з яких 240 мс йде на viewDidLoad в DetailViewController, а в ньому 200 мс — це синхронний NSJSONSerialization.jsonObject на main thread». Саме за такою точністю — до CPU-профілювальника. Без нього 80% «оптимізацій» не приносять результату.
Чому CPU-профілювання — перший крок до швидкого додатку?
Instruments запускається через Xcode → Product → Profile або ⌘I. Для CPU використовуємо Time Profiler (sampling-профілювальник, 1 мс інтервал за замовчуванням) або CPU Profiler (instrumentation-based, точніше, але з overhead до 30%). Sampling-режим ефективніший для первинної діагностики: overhead нижчий і call tree легше читати.
Time Profiler — перший вибір для більшості задач. Показує call tree з часом виконання кожного методу. Критичні налаштування:
- Hide System Libraries — прибираємо шум від системних фреймворків, бачимо тільки свій код.
- Separate by Thread — розуміємо, на якому потоці гальмує.
- Invert Call Tree — показує «листя» дерева викликів, тобто методи, де реально витрачається час.
Типовий сценарій: записуємо 10 секунд роботи додатку, відкриваємо call tree. [MyImageProcessor processImage:] займає 67% CPU. Розкриваємо — там vImageScale_ARGB8888 викликається на main thread з didSelectRowAt. Виносимо в DispatchQueue.global(qos: .userInitiated), результат застосовуємо через DispatchQueue.main.async — проблема вирішена. Час виконання операції скорочується в 3-4 рази, а швидкість скролу відновлюється.
Signposts та os_log для точного вимірювання
Системний профілювальник має overhead та шум. Для точного заміру конкретної операції — os_signpost:
import os.signpost let log = OSLog(subsystem: "com.app", category: "Performance") let id = OSSignpostID(log: log) os_signpost(.begin, log: log, name: "Image Processing", signpostID: id) processImage(data) os_signpost(.end, log: log, name: "Image Processing", signpostID: id) В Instruments → Logging track бачимо точні часові мітки. Це дозволяє вимірювати не «де гальмує в цілому», а «скільки конкретно займає ця операція при різних вхідних даних». Використання os_signpost дозволяє отримати точність вимірювань у 100 разів вищу, ніж при використанні звичайного логу. Додавання signpost-розмітки окупається при кожному наступному профілюванні.
Як читати flame graph?
У сучасних версіях Xcode Time Profiler показує flame graph. Широкі горизонтальні прямокутники — методи, що споживають багато часу. Вкладеність показує стек викликів. Головне правило: дивитися на плато — широкі блоки без дочірніх методів. Це «дно» стеку, де реально витрачається час. Наприклад, плато на NSJSONSerialization шириною 200 мс — явний кандидат на вивантаження в фон.
Android Studio Profiler: CPU
Android Studio CPU Profiler підтримує три режими:
| Режим | Коли використовувати | Overhead |
|---|---|---|
| Sample Java/Kotlin Methods | Первинна діагностика | Низький (1-5%) |
| Trace Java/Kotlin Methods | Точний аналіз, потрібен повний стек | Високий (до 30%) |
| Sample C/C++ Functions | Native код, NDK | Низький |
| System Trace | Системні події, janky frames | Мінімальний |
System Trace — найбільш інформативний для аналізу jank. Показує Choreographer#doFrame, RenderThread, hwuiTask, binder-виклики. Видно конкретний кадр, який затримався, і чому.
Запис через UI або програмно:
Debug.startMethodTracing("myapp_trace") // операція Debug.stopMethodTracing() Файл .trace відкривається в Android Studio Profiler для аналізу.
Типові знахідки на Android
Профілювання показало: при відкритті екрану чату 180 мс йде на SharedPreferences.getAll() — розробник завантажував всі налаштування при кожному відкритті для перевірки прапорця. SharedPreferences на головному потоці з великим файлом (2 MB через кешовані дані) — реальний блокувальник UI. Перехід на DataStore з фоновим читанням через Flow прибрав цю затримку повністю. Економія часу — 180 мс на кожному відкритті.
Часті проблеми на iOS
Синхронний NSJSONSerialization на main thread, завантаження зображень без кешу в UITableViewCell, надлишкові виклики setNeedsDisplay — ці 3 патерни зустрічаються в 70% iOS-проектів з проблемами чуйності. Усунення перших 2 дає приріст FPS з 30 до 60 без архітектурних змін.
Як ми проводимо профілювання: етапи
- Аналітика — визначаємо ключові користувацькі сценарії (скрол стрічки, відкриття екрану, завантаження контенту).
-
Проектування заміру — додаємо
os_signpost/Trace.beginSectionдля критичних операцій. - Реалізація — запис сесій під навантаженням (реальний девайс, бойова збірка).
- Тест — розбір call tree та flame graph, фіксація top-3 проблем.
- Деплой — передача звіту та коду з виправленнями.
Порівняння інструментів:
| Параметр | Instruments (iOS) | Android Profiler |
|---|---|---|
| Метод збору | Sampling / Instrumentation | Sampling / Trace |
| Перегляд стеку | Call Tree + Flame Graph | Flame Chart + Top Down |
| Overhead на запис | 1-5% (sampling) | 1-10% (sampling) |
| Точність до | 1 мс (sampling) | 0.1 мс (trace) |
Документація Google Developers уточнює, що System Trace найбільш точний для jank.
Що входить в роботу
- Підготовка скриптів для автоматичного запуску профілювання (UI automation + Benchmark режим).
- Первинний запис сесій (10-15 хв активного використання додатку).
- Формування PDF-звіту з call tree, flame graph та анотованими скріншотами.
- Рекомендації щодо виправлення з прикладом коду (на Swift/Kotlin).
- Повторне профілювання після змін для підтвердження результату.
Терміни: профілювання та аналіз — від 1 до 2 днів. Усунення проблем — від 2 днів до 2 тижнів залежно від складності. Вартість аудиту розраховується індивідуально. Вартість аудиту зі звітом визначається після аналізу. Усунення виявлених проблем — також оцінюється індивідуально. Оцінюємо проект безкоштовно після ознайомлення з кодом. Гарантуємо зниження завантаження CPU на головному потоці щонайменше на 30%.
Більше 50 проектів з оптимізації продуктивності та 7 років досвіду в мобільній розробці — наші інженери знають, як знайти та усунути вузькі місця.
Отримайте консультацію з оптимізації CPU вашого додатку — зв'яжіться з нами. Замовте профілювання та отримайте звіт з конкретними рекомендаціями.







