Застосунок, який розряджає телефон за пів дня, отримує однозіркові відгуки та видаляється. iOS покаже його в розділі «Високе енергоспоживання» в налаштуваннях, а Android з API 26+ переведе в Doze-режим. Проблема майже ніколи не в одному великому витоку — зазвичай це кілька дрібних: GPS не відключається у фоні, WebSocket пінгує кожні 5 секунд, фоновий Worker спрацьовує занадто часто. Ми, як інженери з мобільної оптимізації, провели понад 80 таких аудитів і гарантуємо, що після нашої роботи застосунок працює на 30% довше від одного заряду. За роки практики ми навчилися виявляти навіть приховані патерни енергоспоживання, які не видно при поверхневому аналізі. Зв'яжіться з нами, щоб обговорити оптимізацію вашого проєкту.
Тестування споживання батареї мобільним застосунком
iOS: Xcode Energy Organizer та Instruments
Instruments → Energy Log — базовий інструмент. Показує активність CPU, GPU, мережі, GPS та екрану у часі. Кожен «сплеск» активності — витрата енергії. Energy Impact в Xcode Debug Navigator: Low / High / Very High — груба оцінка в реальному часі. Для точних вимірювань — XCTMetric:
func testBackgroundSyncEnergyImpact() throws { let metrics: [XCTMetric] = [XCTCPUMetric(), XCTMemoryMetric(), XCTClockMetric()] let options = XCTMeasureOptions() options.iterationCount = 5 measure(metrics: metrics, options: options) { // симулюємо фонову синхронізацію let expectation = self.expectation(description: "sync") BackgroundSyncService.shared.sync { expectation.fulfill() } wait(for: [expectation], timeout: 30) } } XCTCPUMetric + XCTClockMetric дають дані про навантаження CPU та реальний час виконання. Якщо cpuTime зростає нелінійно при збільшенні кількості ітерацій — десь накопичується стан.
Типові проблеми на iOS
CLLocationManager без pausesLocationUpdatesAutomatically = true та без явного stopUpdatingLocation() при переході у фон продовжує працювати і садить батарею. Правильна стратегія для більшості застосунків — requestWhenInUseAuthorization() замість requestAlwaysAuthorization(), і перемикання на startMonitoringSignificantLocationChanges() коли точність не критична.
Timer з Timer.scheduledTimer(withTimeInterval: 1.0, ...) на main run loop, забутий при переході у фон — ще одна класика. Перевіряємо: всі Timer інвалідизуються в applicationDidEnterBackground або в deinit view controller.
Android: Battery Historian та Perfetto
Battery Historian — веб-інструмент від Google для аналізу bug report:
adb bugreport bugreport.zip # Відкриваємо в https://bathist.ef.lc/ або локально через Docker docker run -d -p 9999:9999 gcr.io/android-battery-historian/stable:3.1 --port 9999 На таймлайні бачимо: wakelock'и (хто не дає процесору засинати), синхронізації, GPS-активність, мережеві запити. WakeLock з ім'ям myapp:background_sync що тримається 40 хвилин з 60 — червоний прапор.
Перевірка wakelocks через adb:
adb shell dumpsys power | grep -A 3 "Wake Locks:" adb shell dumpsys battery | grep level WorkManager та енергоефективність
WorkManager — правильний спосіб фонових завдань на Android. Неправильна конфігурація вбиває батарею:
// Погано: мінімальний інтервал 15 хвилин за замовчуванням val syncRequest = PeriodicWorkRequestBuilder<SyncWorker>(15, TimeUnit.MINUTES).build() // Краще: прив'язуємо до мережевого підключення, батарея не розряджена val syncRequest = PeriodicWorkRequestBuilder<SyncWorker>(1, TimeUnit.HOURS) .setConstraints( Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) .setRequiresBatteryNotLow(true) .build() ) .build() SetRequiresBatteryNotLow(true) — Worker не запуститься, якщо заряд нижче ~20%. SetRequiredNetworkType(NetworkType.CONNECTED) — не буде спроб, коли немає мережі.
Perfetto — більш детальний трейсинг для Android. Показує активність на рівні треків CPU, мережі, I/O. Корисний коли Battery Historian показує проблему, але не локалізує її до конкретного коду.
Як виявити проблеми з батареєю на iOS?
Почніть з Energy Log в Instruments. Якщо бачите часті сплески CPU кожні 5 секунд – перевірте WebSocket-пінги. Порівняйте час роботи при увімкненому та вимкненому фоновому оновленні. Для точності використовуйте XCTMetric з кількома ітераціями – це покаже, чи є накопичення навантаження.
Що робити з мережевими запитами?
Кожен підйом радіо-модуля (WiFi або LTE) — пік споживання. Радіо залишається активним 10–30 секунд після останнього запиту (tail energy). Замість 10 запитів по 1 об'єкту краще 1 запит на 10 об'єктів — один підйом замість десяти. Для WebSocket: пінги кожні 5 секунд у фоні — це 12 підйомів радіо за хвилину. Розумний інтервал — 30–60 секунд, з урахуванням NAT-таймаутів.
| Типова проблема | Частота | Рішення |
|---|---|---|
| WebSocket-пінги кожні 5 с | 70% проєктів | Інтервал 60 с з exponential backoff |
| GPS у фоні без пауз | 50% | PausesLocationUpdates = true |
| WorkManager з мінімальним інтервалом | 40% | Constraints + період 1 година |
| Критерій | iOS (Swift) | Android (Kotlin) |
|---|---|---|
| Інструмент профілювання | Instruments Energy Log | Battery Historian / Perfetto |
| Метрики навантаження | CPU, GPU, мережа, GPS, екран | Wakelock, sync, GPS, мережа |
| Юніт-тести | XCTMetric | WorkManager TestListen |
| Типова проблема | Timer у фоні | WakeLock без таймауту |
| Рішення | Інвалідація в background | Constraints + періодичність |
Покрокова інструкція тестування батареї
- Зніміть профіль Energy Log на iOS або bug report на Android протягом 1 години нормального використання.
- Відкрийте в Instruments або Battery Historian та відфільтруйте сплески тривалістю більше 10 секунд.
- Перевірте кожен сплеск — що його викликало: мережевий запит, GPS, таймер, wakelock.
- Оцініть необхідність: чи можна відкласти, об'єднати, зменшити частоту.
- Застосуйте патч — переконфігуруйте WorkManager, поставте пінг-інтервал 60 секунд, відключіть GPS у фоні.
- Повторіть профілювання — переконайтеся, що сплески зникли або скоротилися.
Що входить у роботу з аудиту батареї
Наш аудит включає повний цикл: профілювання на реальних пристроях (iPhone 15, Xiaomi 13 Pro), аналіз логів з виявленням вузьких місць, надання детального звіту з графіками енергоспоживання та рекомендаціями щодо виправлення в коді. Після звіту ми проводимо консультацію з вашою командою для впровадження оптимізацій. При необхідності — повторне профілювання після патча. Ми також допомагаємо з налаштуванням CI/CD для автоматичного відстеження енергоспоживання. Замовте тестування, щоб ваш застосунок працював довше без підзарядки. Зв'яжіться з нами для консультації — ваш проєкт може бути наступним у нашій статистиці успішних оптимізацій.
Ми гарантуємо, що наш досвід (понад 5 років на ринку, 80+ проаналізованих проєктів) допоможе знайти навіть приховані проблеми. Вартість аудиту окупається в середньому за 3 місяці за рахунок зниження скарг користувачів. Отримайте консультацію вже сьогодні — зв'яжіться з нами, щоб обговорити ваш проєкт. Замовте тестування і продовжте життя акумулятору ваших користувачів!







