Lag di aplikasi mobile adalah keterlambatan yang terlihat antara tindakan pengguna dan reaksi antarmuka, yang terjadi karena kelebihan beban thread utama, kebocoran memori, atau operasi input-output yang tidak optimal. Berbeda dengan bug yang terkait dengan kesalahan logika, lag adalah masalah kinerja: aplikasi berjalan dengan benar tetapi lambat. Menurut AppDynamics Mobile App Performance Report 2024, 62% pengguna menghapus aplikasi jika aplikasi tersebut lemot lebih dari 3 detik. Diagnosis lag memerlukan profiling CPU, memori, dan jaringan menggunakan Android Studio Profiler dan Xcode Instruments.
Poin Utama
Lag (dari bahasa Inggris lag) di aplikasi mobile adalah keterlambatan yang terasa secara subjektif antara tindakan pengguna (sentuhan, gesekan, input teks) dan reaksi antarmuka. Secara teknis, lag diukur sebagai waktu antara peristiwa input dan render penuh frame: ambang nyaman — hingga 100 ms, terlihat — dari 200 ms, kritis — lebih dari 500 ms.
Dalam terminologi pengguna, „ngelag” dan „lemot” sering digunakan secara bergantian, tetapi secara teknis lag adalah keterlambatan tetap (misalnya 300 ms setiap klik), sedangkan „lemot” adalah perlambatan tidak tetap: aplikasi kadang berjalan mulus, kadang membeku selama satu detik. Bug, tidak seperti lag, berkaitan bukan dengan kecepatan tetapi dengan kebenaran tampilan.
Google Play dan App Store mempertimbangkan indikator kinerja dalam peringkat aplikasi. Tingkat ANR, frekuensi jank, dan waktu mulai memengaruhi visibilitas di pencarian dan konversi instalasi. Aplikasi dengan lag terus-menerus kehilangan hingga 40% pengguna setelah peluncuran pertama.
Lag terjadi ketika thread utama UI tidak mampu memproses frame pada kecepatan 60 FPS (16.6 ms per frame) atau 120 FPS (8.3 ms). Mari kita lihat sumber utama keterlambatan.
Setiap operasi sinkron di thread UI — membaca dari SharedPreferences, bekerja dengan database melalui Room tanpa suspend, mendekode gambar ke Bitmap — memblokir render frame. Di Android, ini menyebabkan frame terlewat (jank), di iOS — keterlambatan render Core Animation.
Ketika Garbage Collector di Android atau ARC di iOS membebaskan memori, semua thread berhenti. Jeda GC yang sering terjadi saat membuat banyak objek sementara — misalnya, setiap kali adapter daftar dipanggil, instance ViewHolder baru dibuat. Ini muncul sebagai scroll yang tersendat.
ConstraintLayout bersarang, beberapa LinearLayout, View yang tumpang tindih — setiap sarangan meningkatkan waktu measure dan layout pass. Xcode menunjukkan bahwa hierarki lapisan yang dalam (lebih dari 10 level) menyebabkan penurunan FPS sebesar 20-30%.
Untuk mengidentifikasi penyebab lag, digunakan profiler bawaan IDE dan alat pemantauan sistem. Setiap alat menyelesaikan tugasnya masing-masing.
CPU Profiler menunjukkan metode mana yang menghabiskan waktu prosesor dan di thread mana metode tersebut dijalankan. Jika metode dengan perhitungan berat dijalankan di main thread — itulah akar masalahnya. Rekaman jejak dengan sample Java Method diaktifkan memungkinkan melihat tumpukan panggilan di setiap momen dan menemukan „titik panas”.
Alat analog untuk iOS — Time Profiler — mengumpulkan sampel tumpukan setiap milidetik dan menunjukkan berapa persen waktu CPU yang digunakan setiap metode. Kombinasi dengan bendera Main Thread Only memfilter hanya operasi di thread utama, yang secara langsung menunjukkan sumber lag.
Permintaan jaringan yang lambat menciptakan kesan lag, bahkan jika thread UI tidak terblokir. Network Profiler di Android Studio dan Network Link Conditioner di Xcode memungkinkan simulasi koneksi lambat dan melihat bagaimana aplikasi berperilaku dalam kondisi nyata. Respons chunked tanpa kemajuan dan muatan JSON besar adalah sumber umum lag yang tampak.
Contoh profiling permintaan jaringan dengan OkHttp dengan pengukuran waktu:
class TimingInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val start = System.nanoTime()
val response = chain.proceed(chain.request())
val duration = (System.nanoTime() - start) / 1_000_000
Log.d("Pengaturan waktu", "Permintaan memakan waktu $duration ms")
return response
}
}
Penanganan lag memerlukan kerja sistematis: dari optimalisasi satu metode hingga perubahan arsitektur. Mari kita lihat teknik yang paling efektif.
Kotlin Coroutines dengan dispatcher Dispatchers.IO untuk permintaan jaringan dan Dispatchers.Default untuk perhitungan memastikan thread utama tetap bebas untuk UI. Di iOS, Grand Central Dispatch dengan queue .global(qos: .userInitiated) untuk tugas latar belakang dan .main untuk pembaruan UI — pendekatan standar. Hindari operasi sync antar antrean.
RecyclerView di Android dan UICollectionView di iOS memerlukan konfigurasi yang benar: ViewHolder dengan pembuatan objek minimal di onBindViewHolder, DiffUtil untuk menghitung perubahan, prefetching untuk memuat data lebih awal. Di iOS, gunakan diffable data source untuk pembaruan animasi tanpa manajemen manual.
Memuat gambar yang sama setiap kali scroll — lag yang terjamin. Coil (Android) dan Kingfisher (iOS) menyimpan cache gambar di memori dan disk, memastikan tampilan instan saat permintaan berulang. Untuk data, gunakan Room dengan lapisan cache berbasis Flow atau Combine.
Contoh konfigurasi caching gambar dengan Coil di Android:
val imageLoader = ImageLoader(context) {
memoryCachePolicy(CachePolicy.ENABLED)
diskCachePolicy(CachePolicy.ENABLED)
crossfade(true)
size(512, 512)
}
// Memuat dengan caching otomatis diaktifkan
imageView.load("https://example.com/image.jpg") {
placeholder(R.drawable.placeholder)
error(R.drawable.error)
}
Mencegah lag lebih murah daripada memperbaikinya di produksi. Tindakan pencegahan dibangun ke dalam proses pengembangan di tingkat alat dan arsitektur.
StrictMode — alat bawaan Android yang mendeteksi operasi input-output acak dan panggilan jaringan di thread utama pada tahap pengembangan. Aktifkan di Application.onCreate dengan kebijakan penaltyDeath untuk pelanggaran kritis. Ini adalah satu-satunya cara untuk memastikan pengembang melihat masalah sebelum commit.
Analog untuk iOS — Main Thread Checker di Xcode, bagian dari Runtime Sanitization. Ini secara otomatis memeriksa bahwa semua panggilan UIKit dan AppKit dijalankan dari thread utama. Aktifkan di skema build Debug dan capai nol peringatan di CI.
Tambahkan ke pipeline CI menjalankan Macrobenchmark (Android) dan XCTMetrics (iOS) untuk mengukur waktu mulai, FPS scroll, dan penggunaan memori. Tetapkan ambang: jika commit baru meningkatkan waktu mulai lebih dari 5% — build gagal.
Pertanyaan yang Sering Diajukan
Lag adalah sensasi subjektif keterlambatan yang dapat terjadi bahkan pada FPS tinggi jika keterlambatan disebabkan oleh waktu pemrosesan input, bukan rendering. FPS rendah (kurang dari 30 frame/detik) — salah satu penyebab lag, tetapi bukan satu-satunya.
Gunakan Frame Timing API di Android (Choreographer) dan CADisplayLink di iOS untuk mengukur waktu antar frame. Google Play Vitals menunjukkan tingkat jank dalam kondisi nyata. Untuk pengukuran akurat, gunakan Macrobenchmark dengan skenario scroll.
Perangkat lama memiliki lebih sedikit inti CPU, lebih sedikit RAM, dan memori lebih lambat. Operasi yang memakan 5 ms di flagship, di perangkat murah bisa memakan 50 ms. Uji kinerja di perangkat kelas bawah dan atur Baseline Profiles untuk kompilasi AOT.
Ya, ini adalah salah satu cara paling efektif. Gambar resolusi tinggi memakan banyak memori dan waktu CPU untuk decoding. Gunakan downscale ke ukuran View, format WebP (Android) dan HEIC (iOS), serta caching melalui Coil atau Kingfisher.
SwiftUI secara otomatis mengoptimalkan pembaruan melalui diffing, yang mengurangi risiko lag saat data berubah. Namun, hierarki kompleks dan rekonstruksi body yang sering dapat menyebabkan penurunan FPS. UIKit memberikan kontrol lebih atas kinerja, tetapi memerlukan optimalisasi manual.
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