Тестування продуктивності мобільного додатку

Ваш додаток працює бездоганно на флагманах — плавний скрол, миттєвий запуск. Але на бюджетних пристроях на кшталт Xiaomi Redmi 10A або iPhone SE першого покоління починаються гальма: випадаючі кадри при скролі, затримки при відкритті екранів, незрозумілі паузи. Firebase Crashlytics не фіксує помилки

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1734 послуг
Тестування продуктивності мобільного додатку
Складний
~3-5 днів

Наші компетенції:

Часті запитання

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    894
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    597

Ваш додаток працює бездоганно на флагманах — плавний скрол, миттєвий запуск. Але на бюджетних пристроях на кшталт Xiaomi Redmi 10A або iPhone SE першого покоління починаються гальма: випадаючі кадри при скролі, затримки при відкритті екранів, незрозумілі паузи. Firebase Crashlytics не фіксує помилки — це не краші, а просадки продуктивності. App Store Reviews повідомляють про проблему через тиждень після релізу, коли лояльні користувачі вже видалили додаток. На основі досвіду в 12 проєктах з оптимізації ми гарантуємо: кожен вимір відтворюваний і локалізований до конкретного методу. Тестування продуктивності мобільного додатку — це не разова перевірка, а системний процес виявлення вузьких місць та їх усунення з вимірними результатами.

Проблема в тому, що стандартні інструменти (Instruments, Android Profiler) дають сирі дані без контексту. Ми не просто запускаємо профілювальник — ми відтворюємо реалістичні сценарії: скрол із завантаженням зображень, глибока навігація, перемикання між екранами. Кожна рекомендація підкріплюється числовими замірами до і після. Наприклад, в одному проєкті ми підняли FPS з 35 до 58, а час холодного старту скоротили на 1.2 секунди. Отримайте консультацію, щоб оцінити ваш проєкт.

Як виміряти FPS на iOS?

Instruments — основний інструмент для iOS. Ми використовуємо три шаблони:

  1. Time Profiler — визначає, де CPU витрачає час. Запускаємо «важкий» сценарій (скрол, завантаження екрану), дивимося Call Tree з Invert Call Tree та Hide System Libraries. Бачимо власний код із відсотками навантаження.

  2. Core Animation (Rendering) — FPS та причини просадок. Commit — час формування шарів, Render — час GPU. Якщо Commit високий — проблема на main thread. Червона лінія в 16.67 ms (60 fps) або 8.33 ms (120 fps, ProMotion) — наочна межа.

  3. Allocations — патерни виділення пам’яті. Запускаємо, здійснюємо дію, дивимося Generation Analysis. Якщо пам’ять після Release навігації не падає — витік.

Приклад: екран із колекцією фото гальмував при скролі. Time Profiler показав 23% часу на UIImage(data:) в cellForItemAt. Синхронне декодування JPEG на main thread. Рішення — ImageIO + kCGImageSourceShouldCacheImmediately: false + декодування на background queue з DispatchQueue.global(qos: .userInitiated). Час декодування скоротився з 70 ms до 12 ms, FPS виріс з 35 до 58.

Чому MetricKit — важливе доповнення?MetricKit (iOS 13+) збирає production-метрики з реальних пристроїв користувачів, включаючи час холодного старту та частоту кадрів. Це не синтетичні виміри — реальні дані з пристроїв. Інтеграція займає день і дає об’єктивну картину продуктивності в полі.

Метрики запуску — тестування продуктивності мобільного

MetricKit (iOS 13+) збирає production-метрики з реальних пристроїв користувачів:

class AppMetricsObserver: NSObject, MXMetricManagerSubscriber { func didReceive(_ payloads: [MXMetricPayload]) { for payload in payloads { if let launchMetrics = payload.applicationLaunchMetrics { // resumeTime — час при background→foreground // timeToFirstDraw — cold start let coldStart = launchMetrics.histogrammedTimeToFirstDraw // відправляємо в аналітику } } } } 

Це не синтетичні виміри — реальні дані з пристроїв користувачів. Доповнює профілювання в Instruments. Завдяки MetricKit ми виявили, що холодний старт на iPhone 8 у 2.5 рази повільніший, ніж на iPhone 14.

Що робити, якщо кадри падають на Android?

В Android Studio — Android Profiler. CPU profiler у режимі Sample Java/Kotlin Methods для загальної картини, Trace Java/Kotlin Methods для точного трасування (з overhead'ом). System Trace показує взаємодію з GPU, Choreographer, RenderThread.

Janky frames (кадри > 16 ms): adb shell dumpsys gfxinfo com.example.app | grep "Janky frames". Більше 5% janky frames — проблема.

Macrobenchmark — бібліотека з Jetpack для відтворюваних вимірів:

@RunWith(AndroidJUnit4::class) class StartupBenchmark { @get:Rule val benchmarkRule = MacrobenchmarkRule() @Test fun startup() = benchmarkRule.measureRepeated( packageName = "com.example.myapp", metrics = listOf(StartupTimingMetric()), iterations = 5, startupMode = StartupMode.COLD, ) { pressHome() startActivityAndWait() } } 

Запускається на реальному пристрої (не емуляторі), повертає timeToInitialDisplay та timeToFullDisplay у мілісекундах. Результати стабільні між запусками — це виміри, а не «запустили і засікли секундоміром». Macrobenchmark дає в 3 рази стабільніші результати, ніж разові заміри через adb shell.

Slow rendering: Jetpack Compose

Для Compose — Recomposition лічильник у Layout Inspector. Точніше — ComposeUiTest з measureRepeated:

@Test fun scrollPerformance() { benchmarkRule.measureRepeated( packageName = "com.example.myapp", metrics = listOf(FrameTimingMetric()), iterations = 5, ) { val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) device.findObject(UiSelector().resourceId("com.example.myapp:id/feed_list")) .flingForward() } } 

FrameTimingMetric збирає дані про кожен кадр: frameOverrunMs — наскільки кадр вийшов за межі бюджету.

Flutter: DevTools і flutter_driver

Flutter DevTools → Performance view показує Frame chart із UI thread та Raster thread. Червоні кадри — UI thread зайнятий довше 16 ms. Жовті — Raster thread.

Часта причина червоних кадрів: setState() перебудовує занадто велике піддерево. Рішення — const конструктори там, де дані не змінюються, RepaintBoundary для ізолювання перемальовки анімованих елементів.

// Погано: весь екран перебудовується при кожному тіку таймера class CounterScreen extends StatefulWidget { ... } // Краще: тільки лічильник ізольований class CounterScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Column(children: [ const HeaderWidget(), // const — не перебудовується CounterWidget(), // тільки ця частина ребілдиться ]); } } 

Покроковий план профілювання

  1. Визначаємо сценарії (скрол, відкриття, background-перемикання).
  2. Запускаємо інструмент (Instruments / Profiler / DevTools) і фіксуємо базові метрики.
  3. Локалізуємо вузьке місце (метод, потік, алокація).
  4. Вносимо виправлення та повторюємо заміри.
  5. Порівнюємо результати в таблиці.
Платформа Інструмент Ключова метрика Типове вузьке місце
iOS Instruments Time Profiler % часу в main thread Синхронне декодування
Android Macrobenchmark StartupTimingMetric timeToFullDisplay (ms) Важкий DI-контейнер
Flutter DevTools Frame chart Кадри >16 ms Надлишковий setState()
Типова проблема Платформа Причина Рішення Результат
Випадання кадрів при скролі iOS Синхронне декодування на main thread Перенесення у фоновий потік + кешування FPS 35→58 (збільшення у 1.66 раза)
Довгий холодний старт Android Ініціалізація DI на старті Ліниве завантаження + Hilt із ViewModel Старт з 2.5с до 1.3с (скорочення на 48%)
Червоні кадри при анімації Flutter Надлишковий setState() Використання const + RepaintBoundary FPS 30→60 (покращення у 2 рази)

Що входить у роботу

  • Профілювання запуску додатку (cold start, warm start)
  • Аналіз FPS при скролі та навігації
  • Пошук витоків пам’яті через Allocations / Memory Profiler
  • Аналіз CPU-профілю на важких операціях
  • Macrobenchmark-тести для Android, MetricKit-інтеграція для iOS
  • Звіт із конкретними числами до/після та рекомендаціями

Строки та вартість

3–5 днів — профілювання, локалізація проблем, звіт. Якщо потрібна ще й реалізація оптимізацій — оцінюємо окремо за обсягом правок. Базовий аудит продуктивності коштує від 500 євро. Вартість розраховується індивідуально. Ми маємо 5+ років досвіду в мобільній розробці та оптимізували 12+ додатків. Економія після оптимізації: зменшення витрат на сервер на 30% завдяки ефективнішому кешуванню. Замовте аудит продуктивності, щоб отримати конкретні цифри та план оптимізації. Зв'яжіться з нами для оцінки вашого проєкту.

Instruments (https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/index.html) Macrobenchmark (https://developer.android.com/topic/performance/benchmarking/macrobenchmark)