Profiling (профилисање) је процес мерења перформанси апликације по кључним метрикама: оптерећење CPU, потрошња меморије, мрежни саобраћај и потрошња енергије. Циљ профилисања је проналажење уских грла која успоравају апликацију или изазивају прекомерну потрошњу ресурса. Према Android Developers, редовно профилисање у фази развоја смањује број перформанс багова на продукцији до 60% и помаже у одржавању глатког UI чак и на слабијим уређајима.
Главне ставке
Profiling је прикупљање и анализа података о раду апликације: које функције се извршавају, колико времена трају, колико меморије троше и како комуницирају са мрежом. За разлику од логовања, профилисање ради на нивоу система и даје прецизне нумеричке метрике, а не субјективне процене.
Главни циљ профилисања је проналажење делова кода који неоптимално користе ресурсе. То могу бити споре методе које се позивају у UI нити, цурења меморије, неефикасни SQL упити, непотребни мрежни позиви или прекомерна потрошња енергије. Без профилисања, програмери поправљају оно што „изгледа споро“, уместо да се ослањају на стварне податке.
Према подацима Google I/O 2023, апликације које пролазе кроз редовно профилисање у фази развоја показују 40% мање ANR (Application Not Responding) грешака и 50% мање падова због OutOfMemory. Алати за профилисање су уграђени у сва савремена IDE — Android Studio Profiler за Android и Xcode Instruments за iOS.
Профилисање може бити статичко (анализа кода без покретања — lint, Detekt) и динамичко (мерења током извршавања апликације). За проналажење стварних проблема са перформансама користи се динамичко профилисање, које приказује стварно понашање апликације на уређају или емулатору.
Профилисање је неопходно пре сваког великог издања, при имплементацији тешких UI компоненти (листе, анимације, прилагођени View), при жалбама корисника на успоравања и пражњење батерије, као и након промене архитектуре апликације. Систематски приступ — спроводите профилисање у сваком спринту, бележећи baseline метрика.
CPU профилисање прати које методе и нити оптерећују процесор и колико времена траје извршење сваког позива. Главни задатак је проналажење функција које раде дуже од очекиваног и блокирају UI нит, изазивајући испуштање кадрова (jank) и ANR.
У Android CPU Profiler-у се приказује Top-Down tree — стабло позива, где се може видети која метода се најдуже извршава у контексту одређене нити. На iOS Instruments Time Profiler ради на принципу узорковања: у једнаким временским интервалима (нпр. 1 ms) систем бележи стек позива сваке нити. На основу статистике узорковања одређује се који код заузима највише времена.
// Пример: спора метода која изазива jank
class UserAdapter : RecyclerView.Adapter<UserViewHolder>() {
override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
// ❌ Ова метода се позива у UI нити и блокира приказивање
// Профилисање ће показати да decompressImage заузима 80% времена
val user = getItem(position)
val bitmap = ImageUtils.decompressImage(user.avatar)
holder.avatarView.setImageBitmap(bitmap)
}
}
При профилисању CPU треба обратити пажњу на методе са високим Self Time — то је време које метода проводи на свом раду, не рачунајући позиве метода потомака. Ако Self Time методе у UI нити прелази 16 ms — то гарантује испуштање кадра на 60 FPS екрану. Решење — пребацити тешке операције у позадинску нит.
Меморијско профилисање прати колико меморије користи апликација: који објекти се креирају, колико дуго живе и када се ослобађају. Главни задатак је проналажење цурења (објекти који не би требало да постоје, али остају у меморији) и непотребних алокација (објекти који се пречесто креирају).
У Android Memory Profiler-у се приказује график потрошње RAM-а у реалном времену, листа свих алопираних објеката и детаљи за сваки тип. Кључне метрике: Java Heap (објекти у JVM хипу), Native Heap (алокације на C/C++ нивоу), Graphics Memory (текстуре и GPU бафери). За iOS Instruments Allocations приказује сличне метрике: Heap Allocations (објекти у хипу) и Anonymous VM (странице виртуелне меморије).
| Метрика | Android Profiler | Instruments (iOS) |
|---|---|---|
| Објекти хипа | Java Heap + Native Heap | Heap Allocations |
| Графика | Graphics Memory | VM Tracker |
| Цурења | Memory Profiler + LeakCanary | Leaks instrument |
| Дамп хипа | HPROF (Capture) | Heapshot |
При меморијском профилисању важно је узети дамп хипа након типичних корисничких сценарија: отварање и затварање екрана, учитавање листе, рад са сликама. Поређење два дампа (пре и после сценарија) показаће који објекти нису ослобођени. Ако је број објеката Activity порастао, а екран је затворен — то је цурење.
У Android Studio отворите дамп кроз Memory Profiler: сортирајте објекте по Retained Size (што је већи, објекат задржава више меморије). Тражите инстанце Activity, Fragment и Bitmap које не би требало да постоје у меморији. Ако такав објекат постоји — пређите на Reference Tree да бисте видели шта га задржава.
Мрежно профилисање прати све HTTP захтеве апликације: URL, величину одговора, време извршења, кодове одговора и заглавља. Главни циљ је проналажење захтева који трају предуго, преносе непотребне податке или се позивају без потребе.
У Android Network Profiler-у се приказује временска линија свих мрежних позива, њихово трајање и величина пренесених података. Сваки захтев се може отворити за приказ пуног заглавља и садржаја одговора. На iOS Instruments Network за сличне задатке користи надгледање URL Loading System и приказује waterfall дијаграм захтева.
Типични проблеми које открива мрежно профилисање: недостатак кеширања (исти JSON се учитава при сваком отварању екрана), дуплирани захтеви (више компоненти истовремено захтева исте податке), велики одговори (сервер шаље 5 MB JSON када је потребно 100 KB). За сваки проблем постоји стандардно решење: подесити кеширање кроз OkHttp или URLSession, објединити претплате кроз Combine или Flow, додати пагинацију на серверу.
Посебну пажњу обратите на први бајт (TTFB — Time To First Byte). Ако TTFB прелази 500 ms при доброј вези — проблем је на серверској страни. Ако је сам захтев брз, али парсирање JSON траје секунде — проблем је у десеријализацији и треба је профилисати одвојено.
Енергетско профилисање мери како апликација утиче на ниво батерије. Ово је релативно нов вид профилисања, али критично важан за мобилне апликације — корисници бришу апликације које прекомерно празне батерију. Energy Profiler у Android Studio и Energy Log у Instruments показују које операције (Wi-Fi, GPS, CPU, Bluetooth) троше енергију у сваком тренутку.
Главни потрошачи енергије у мобилним апликацијама: WakeLock (одржавање процесора у активном стању), GPS Location (континуирано ажурирање координата), мрежни захтеви (посебно на мобилној мрежи 4G/5G), анимације у позадини. Energy Profiler поставља догађаје апликације на скалу потрошње енергије — ако на графикону постоји скок, може се тачно одредити која га је операција изазвала.
Према подацима Apple WWDC 2023, смањење потрошње енергије апликације за 20% повећава задржавање корисника за 12%, јер корисници имају тенденцију да бришу апликације које јако празне батерију. Препорука — увек укључите Energy Profiler при тестирању сценарија са GPS-ом, позадинском синхронизацијом и стримовањем.
Избор алата зависи од платформе и типа профилисања. За Android основни сет — Android Studio Profiler (CPU, Memory, Network, Energy), LeakCanary (цурења меморије) и Perfetto (системско профилисање на нивоу кернела). За iOS — Xcode Instruments са сетом шаблона Time Profiler, Allocations, Leaks, Energy Log, Network и Core Animation.
За вишеплатформски развој у Flutter-у користи се DevTools са модулима Timeline (CPU), Memory, Network и Debugger. За React Native — React DevTools и Flipper од Facebook-а, који подржава инспекцију мреже, базе података и UI хијерархије. Без обзира на фрејмворк, основни принципи профилисања су универзални: мерите пре оптимизације и после, бележите baseline, упоређујте метрике при свакој промени кода.
Савремени приступи укључују аутоматизовано профилисање у CI. На Android-у Firebase Test Lab подржава мерења перформанси заједно са UI тестовима: добијате не само pass/fail тестова, већ и графиконе CPU, Memory и Network за сваку итерацију. Аналогну функционалност за iOS пружају GitHub Actions са XCUITest и Instruments CLI.
За брзу проверу једне метрике користите уграђени профилер IDE-а. За комплексну анализу цурења — специјализоване алате (LeakCanary, Instruments Leaks). За системско профилисање на нивоу драјвера — Perfetto (Android) или DTrace (macOS). Комбиновање два-три алата покрива 95% сценарија профилисања.
Често постављана питања
Логовање приказује редослед догађаја у текстуалном облику, док профилисање даје квантитативне метрике — колико времена, меморије, процесора и мреже троши сваки део кода. Профилисање одговара на питање „колико много“, а логовање на питање „шта се догодило“.
Препоручује се спровођење профилисања пре сваког великог издања, при имплементацији нових тешких UI компоненти и када се појаве жалбе на перформансе. У идеалном случају профилисање је уграђено у CI и покреће се аутоматски при сваком pull request-у.
Да, и то је чак пожељније него на емулатору. Реалан уређај приказује стварне перформансе узимајући у обзир ограничења конкретног хардвера. Android Studio Profiler и Xcode Instruments подржавају профилисање на повезаном уређају без икаквих ограничења.
Да, сваки профилер додаје overhead. За CPU профилисање на основу узорковања overhead износи 1–5%. За меморијско профилисање са дамповима хипа — до 10% у тренутку дампа. Савремени алати настоје да минимизирају утицај, али га треба узети у обзир при интерпретацији резултата.
Baseline су референтне метрике перформанси, снимљене на првој стабилној верзији апликације. При свакој промени кода упоређујте нове метрике са baseline-ом. Ако је време покретања порасло за 50 ms у односу на baseline — потребно је пронаћи узрок пре спајања промена.
Закључци
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође