Mengoptimalkan performa aplikasi mobile: memahami rendering & frame rate, sumber jank, memory leaks & baterai, serta memakai tools profiling (Profiler, Instruments, DevTools, Perfetto) untuk menemukan dan memperbaiki bottleneck di Fitku

Fitur lengkap tidak berarti apa-apa jika aplikasi terasa lambat. Di episode 15 ini kita belajar performance & profiling: mengapa layar terasa "laggy", bagaimana mengukur secara objektif, dan tools apa saja yang dipakai profesional untuk menemukan akar masalah. Performa adalah bagian dari UX — pengguna tidak akan memaafkan aplikasi yang janky meski fiturnya hebat.
Mengapa topik ini menantang? Karena masalah performa hampir selalu kontekstual: lambat di satu device, cepat di device lain. Tanpa pengukuran (profiling), kita hanya menebak — dan menebak jarang benar.
Layar di-refresh 60 (atau 120) kali per detik. Setiap refresh adalah satu frame; aplikasi punya waktu ±16ms (60Hz) untuk menghasilkan frame:
┌──────────────────────────────┐
│ Frame budget = 16.6ms (60Hz) │
│ UI thread ───► render │
│ Main queue (layout+draw) │
│ Kegagalan budget = jank/drop │
└──────────────────────────────┘Jank terjadi saat frame melampaui budget — pengguna melihat "tersendat". Sumber jank paling umum: kerja berat di main thread (parsing JSON besar, render list panjang tanpa virtualisasi, layout tidak perlu).
LazyColumn/FlatList/ListView/LazyVStack (virtualisasi).// BURUK: Column + for → semua item di-render
// BAIK: LazyColumn → hanya item terlihat
LazyColumn {
items(workouts, key = { it.id }) { workout ->
WorkoutRow(workout)
}
}Memory leak = objek tidak bisa dibebaskan GC karena masih direferensikan. Gejala: aplikasi membengkak, kemudian OS membunuhnya (OutOfMemory crash). Penyebab umum: observer/listener tidak di-unregister, Context disimpan statis, coroutine/timer tidak dibatalkan.
// BURUK: scope global, berjalan setelah ViewModel mati
val job = CoroutineScope(Dispatchers.IO).launch { ... }
// BAIK: scope yang mati bersama ViewModel
viewModelScope.launch { ... }Baterai boros biasanya karena: lokasi di-polling terus-menerus, wakelock yang tidak dilepas, network sering, atau background service berlebihan (episode 14). Android menyediakan Battery Historian/Battery section di Profiler; iOS punya Energy Log.
Note
Aturan dasar optimasi: ukur dulu, ubah setelah. Lebih dari 70% "optimasi tebakan" tidak berdampak atau malah menurunkan performa. Profiling adalah prasyarat, bukan opsional.
Android Studio Profiler menampilkan CPU, memory, network, energy secara live. Untuk analisis dalam, Perfetto (trace system) menangkap aktivitas seluruh sistem:
adb shell perfetto -o /data/misc/perfetto-traces/trace -t 10s \
sched freq idle atrace gfx view am wm
adb pull /data/misc/perfetto-traces/trace ./trace.perfetto-traceBuka file di ui.perfetto.dev untuk melihat timeline frame, komposisi, dan proses yang bekerja.
Di iOS, Instruments adalah toolkit: Time Profiler (CPU), Allocations & Leaks (memory), Core Animation (rendering). Jalankan lewat Product → Profile (⌘I):
let start = CFAbsoluteTimeGetCurrent()
let items = workouts.filter { $0.isToday }
print("filter: \(CFAbsoluteTimeGetCurrent() - start)s")flutter run + keyboard shortcut) menyediakan Performance overlay, Memory, CPU profiler. Metrik kunci: build time per widget & frame raster.npx react-native-profiler).flutter run --profile → jalankan di mode profil
devtools → Performance → lihat UI & Raster threadBuat baseline sebelum mengoptimasi: FPS rata-rata, frame drop, startup time (cold start), memory puncak. Tanpa baseline, kalian tidak tahu apakah optimasi berhasil.
Langkah nyata saat Fitku terasa lambat:
1. Rekam trace (Perfetto / Instruments / DevTools) saat UI terasa jank
2. Identifikasi frame yang drop → cek thread yang mem-block
3. Baca call stack pada momen drop → temukan fungsi mahal
4. Perbaiki (virtualisasi, cache, lepas observer)
5. Rekam ulang → bandingkan baselineTip
Selalu uji di device kelas menengah atau set throttle emulator (misal CPU throttling di Android Studio). Optimasi yang hanya benar di flagship sering gagal di lapangan. Profiling di perangkat paling lemah yang kalian targetkan adalah pilihan paling aman.
Application.onCreate, inisialisasi berat ditunda.key/reusableIdentifier pada list: reuse view gagal → GC bekerja keras.Warning
Jangan lupa: "fast" tanpa konteks tidak berguna. Gunakan metrik yang terukur — Frame Pacing (Android), HID (iOS), atau skor Firebase Performance Monitoring untuk deteksi anomali di lapangan. Monitoring produksi dibahas lebih jauh di episode 19.
Pada episode 15 ini, kalian telah menguasai dasar optimasi:
Di episode 16 selanjutnya kita jamin kualitas: Testing Mobile — unit test, widget/UI tests, dan e2e (Detox/Maestro/Appium) untuk membangun test suite Fitku. Sampai jumpa!