Nge-lag — adalah deskripsi pengguna tentang situasi ketika aplikasi mobile bekerja lambat dan tidak stabil: kadang merespon normal, kadang tiba-tiba membeku beberapa detik. Dalam konteks teknis “nge-lag” berarti kombinasi lag dan mikro-bekuan yang disebabkan oleh pause GC yang sering, pemblokiran thread utama oleh operasi sinkron, dan struktur data yang tidak optimal. Menurut Android Performance Benchmarking Guide, mengurangi waktu respons dari 300 ms menjadi 100 ms meningkatkan retensi pengguna sebesar 25%. Diagnosis nge-lag membutuhkan kombinasi profiling CPU dan Memory dengan analisis frekuensi pengumpulan sampah.
Poin utama
Nge-lag — istilah informal yang digunakan pengguna untuk menggambarkan kinerja aplikasi yang secara subjektif lambat. Berbeda dengan lag yang muncul sebagai keterlambatan konstan, nge-lag adalah bekuan tidak teratur: aplikasi dapat bekerja sempurna selama beberapa detik, lalu “berpikir” selama 1–3 detik.
Dari sudut pandang profiling, nge-lag muncul sebagai serangkaian frame yang terlewat (jank) dengan keterlambatan puncak lebih dari 100 ms. Pada grafik FPS ini terlihat sebagai penurunan tajam: 60 → 20 → 55 → 10 frame per detik. Berbeda dengan lag dengan FPS rendah yang merata, nge-lag memiliki variabilitas yang jelas.
Ketika aplikasi nge-lag, pengguna tidak memahami logika perlambatan: layar dapat scroll dengan mulus, lalu tiba-tiba berhenti selama satu detik. Ini menyebabkan frustrasi dan mengurangi kepercayaan pada aplikasi. Menurut Google, 53% pengguna meninggalkan situs atau aplikasi jika pemuatan memakan waktu lebih dari 3 detik.
Sifat tidak teratur dari nge-lag menunjukkan bahwa masalah disebabkan oleh faktor kejadian, bukan kelebihan beban konstan. Mari kita lihat skenario tipikal.
Di Android di lingkungan ART, pengumpulan sampah menghentikan semua thread aplikasi. Jika dalam kode banyak objek sementara dibuat — misalnya, setiap panggilan onBindViewHolder membuat String baru melalui konkatenasi — GC lebih sering dimulai. Pause dapat berlangsung 5–50 ms tergantung pada ukuran heap dan generasi objek. Pengguna merasakan ini sebagai “berpikir” mendadak.
Room di Android dan Core Data di iOS mendukung query asinkron, tetapi pengembang sering memanggil getValue() atau menjalankan query melalui runBlocking untuk kesederhanaan. SELECT berat dengan join pada tabel 10.000 baris dapat memakan waktu 200–500 ms, sepenuhnya memblokir UI selama waktu itu.
Memuat gambar kamera (12 Mp, 4000x3000 px) tanpa penskalaan memakan waktu hingga 200 ms untuk decoding ke Bitmap. Jika gambar dimuat secara asinkron tetapi tanpa pool thread dengan batasan, menjalankan 5–6 decoding secara bersamaan dapat membebani CPU secara berlebihan, menyebabkan perlambatan yang berpindah-pindah.
Diagnosis perlambatan tidak teratur lebih sulit daripada diagnosis lag konstan, karena masalah mungkin tidak muncul di setiap startup. Diperlukan pengumpulan statistik selama periode yang lebih lama.
Android Studio Memory Profiler tidak hanya menunjukkan penggunaan memori, tetapi juga peristiwa GC: frekuensi, tipe (Concurrent, Full), durasi. Jika GC terjadi lebih dari 1 kali dalam 5 detik dalam keadaan diam — ini adalah tanda alokasi berlebihan. Merekam heap dump pada saat nge-lag memungkinkan melihat objek mana yang memenuhi memori.
Di iOS gunakan template Allocations di Instruments untuk melacak pembuatan dan pembebasan objek. Aktifkan generasi (Generations) — mereka memungkinkan mengambil snapshot heap di antara tindakan dan melihat objek mana yang tetap di memori. Objek persisten yang tidak dibebaskan — sumber akumulasi memori dan pause berikutnya.
JankStats — pustaka Android yang mengumpulkan metrik frame yang terlewat secara real-time. Ini mengaitkan setiap jank dengan skenario saat ini (misalnya, “scroll daftar”, “membuka layar”), yang memungkinkan untuk memahami pada tindakan mana tepatnya nge-lag terjadi.
Contoh integrasi JankStats untuk melacak bekuan di Android:
class MainActivity : AppCompatActivity() {
private lateinit var jankStats: JankStats
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
jankStats = JankStats.create(this.window.decorView) { frameData ->
if (frameData.isJank()) {
Log.w("Jank", "Duration=${frameData.durationMs}ms")
}
}
}
}
Memperbaiki nge-lag membutuhkan kerja yang terarah dengan setiap penyebab. Tidak ada solusi universal — diperlukan analisis profil kinerja spesifik.
Jika daftar berisi 1000+ elemen dan semuanya dimuat sekaligus — ini adalah nge-lag terjamin. Paging 3 di Android dan NSFetchedResultsController di iOS memuat data dalam potongan saat scroll. Pengguna hanya melihat 10–20 elemen pertama, sisanya dimuat di latar belakang.
Room memungkinkan profiling query melalui Inspection Tool di Android Studio: waktu eksekusi, jumlah baris yang dikembalikan, dan rencana query terlihat. Menambahkan indeks pada kolom WHERE dan ORDER BY dapat mengurangi waktu query dari 300 ms menjadi 5 ms. Di iOS pemeriksaan serupa dilakukan oleh Core Data Profiler di Instruments.
Sinkronisasi latar belakang, unggah file, pemrosesan data — semua ini harus dilakukan melalui WorkManager (Android) atau Background Tasks (iOS). Jika sinkronisasi dimulai di thread UI, aplikasi akan nge-lag selama eksekusi. WorkManager menjamin eksekusi di thread latar belakang dengan mempertimbangkan status baterai dan jaringan.
Contoh sinkronisasi latar belakang melalui WorkManager di Android:
class SyncWorker(context: Context, params: WorkerParameters)
: CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
return try {
Log.d("Sync", "Sinkronisasi data di thread latar belakang")
syncData()
Result.success()
} catch (e: Exception) {
Result.retry()
}
}
}
Nge-lag dapat dicegah di tahap penulisan kode dengan mengikuti prinsip kerja efisien dengan memori dan thread.
Baseline Profiles — daftar kelas dan metode yang dikompilasi Android terlebih dahulu (AOT), bukan JIT. Tanpa profil, setiap layar baru dikompilasi saat pertama kali dibuka, menyebabkan keterlambatan 100–500 ms. Siapkan Baseline Profile untuk layar kunci dan aktifkan generasi di Gradle melalui baseline-profile-gradle-plugin.
Hot path — kode yang dieksekusi di setiap frame: onBindViewHolder, draw, layoutSubviews. Hindari membuat objek di metode ini: gunakan pool objek, StringBuilder alih-alih konkatenasi, cache string yang diformat dan formatter. Setiap alokasi tambahan mendekatkan GC berikutnya.
Tambahkan ke pipeline CI menjalankan Macrobenchmark dengan skenario scroll daftar dan membuka layar. Tetapkan ambang batas: persentil ke-99 waktu frame tidak boleh melebihi 16 ms. Jika ambang batas terlampaui — build ditolak hingga optimasi.
Pertanyaan yang sering diajukan
Lag — keterlambatan konstan (misalnya, 200 ms per ketukan). Nge-lag — tidak teratur: aplikasi bekerja normal, lalu tiba-tiba melambat 1–3 detik, lalu normal lagi. Penyebab — faktor kejadian seperti pause GC atau query sinkron ke database.
Gunakan Memory Profiler di Android Studio: tab Memory menunjukkan peristiwa GC dengan durasi. Untuk pemantauan produksi, hubungkan Firebase Performance Monitoring dengan trace kustom. Di iOS aktifkan Malloc Debug dan tandai generasi alokasi di Instruments.
Secara tidak langsung — ya. Jika respons server datang dengan keterlambatan dan UI menunggunya secara sinkron, aplikasi membeku. Jika permintaan asinkron tetapi pemrosesan respons dilakukan di thread UI — ini juga akan menyebabkan nge-lag. Solusi — pemrosesan asinkron dengan coroutine dan indikator kemajuan.
Jika digunakan tidak benar KMP dapat menghasilkan objek wrapper berlebihan untuk interoperabilitas. Di iOS ini meningkatkan frekuensi alokasi dan akibatnya pause ARC. Gunakan @ObjCName, optimalkan expect/actual dan hindari panggilan sering ke kode bersama dari jalur panas UI.
Meningkatkan heap melalui android:largeHeap="true" menunda GC tetapi tidak menghilangkan penyebab alokasi. Ketika GC akhirnya dimulai, pause akan lebih lama karena lebih banyak objek yang harus dilalui. Solusi — kurangi jumlah alokasi, jangan perbesar heap.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga