Jank untuk aplikasi seluler — apa itu, penyebab dan penanggulangan

Penulis: IT Sectr Diterbitkan: 2026-04-01 Waktu membaca: 10 mnt

Jank — adalah istilah yang menunjukkan kegagapan yang terlihat atau “gagap” dalam animasi antarmuka, yang disebabkan oleh hilangnya bingkai individual. Dalam aplikasi seluler, Jank terjadi ketika waktu rendering bingkai melebihi anggaran yang dialokasikan oleh frekuensi penyegaran layar. Menurut Android Developers, 2025, Jank adalah penyebab utama perasaan subjektif “lembat” — aplikasi mungkin sempurna secara fungsional, tetapi pengguna menganggapnya lambat karena FPS yang tidak stabil.

Poin utama

  • Jank — bingkai yang terlewat, terlihat sebagai kegagapan animasi.
  • Penyebab utama — melebihi anggaran waktu per bingkai (16.6 ms untuk 60 FPS).
  • Jank muncul karena Layout berat, GC panjang, pemblokiran main thread, atau overdraw.
  • Untuk diagnosis digunakan FrameTimeline (Android) dan Instruments (iOS).
  • Penanggulangan Jank meningkatkan NPS dan retensi pengguna sebesar 15–25%.

Apa itu Jank

Jank — adalah istilah dari grafis komputer yang menunjukkan cacat visual di mana animasi bergerak tersentak-sentak, bukan meluncur mulus. Dalam pengembangan seluler, Jank diukur sebagai jumlah bingkai yang terlewat (skipped frames) per satuan waktu. Jika sistem tidak sempat menyiapkan bingkai pada saat VSync, layar mengulang bingkai sebelumnya — terjadi jeda 16.6 ms pada 60 Hz. Satu bingkai yang terlewat mungkin tidak terlihat, tetapi rangkaian 3–5 bingkai yang terlewat secara berurutan menciptakan perasaan “lembat” selama 50–80 ms, yang jelas dirasakan pengguna.

Jank sangat kritis untuk animasi yang harus bekerja dengan kecepatan konstan: scrolling daftar, animasi pembukaan menu, efek paralaks, transisi antar layar. Menurut penelitian UX Google (2024), aplikasi dengan indikator Jank lebih dari 3% sesi scroll menerima 22% lebih banyak ulasan bintang satu dibandingkan aplikasi dengan indikator kurang dari 0.5%. Alat Android Vitals secara otomatis melacak Jank dan mengklasifikasikannya berdasarkan severity: moderate, severe, dan critical.

Penyebab utama Jank

Penyebab Jank dibagi menjadi beberapa kategori. Pertama — Layout Jank: disebabkan oleh requestLayout() yang sering karena perubahan ukuran View, animasi LayoutTransition, atau pemuatan konten dinamis. Setiap panggilan requestLayout memicu Measure + Layout untuk seluruh sub-pohon View, yang dapat memakan waktu 5–30 ms. Kedua — Draw Jank: terkait dengan overdraw dan penggunaan drawable berat. Ketiga — Thread Jank: pemblokiran main thread karena operasi sinkron — memuat file, bekerja dengan database di thread utama, mendekode Bitmap.

Kategori keempat — GC Jank: garbage collection di ART/Dalvik atau Swift ARC. Ketika banyak objek menumpuk di heap, GC memicu jeda Stop-The-World selama 5–15 ms. Di Android, jeda GC paling sering terjadi pada alokasi sering di loop: pembuatan objek di onDraw(), alokasi di adapter, ekspresi lambda yang tidak digunakan. Kelima — IPC Jank: komunikasi antarproses (ContentProvider, Binder) di thread utama. Keenam — Rendering Jank: rendering GPU lambat karena shader yang tidak optimal atau tekstur berukuran besar.

Tipe JankPenyebabDurasi tipikalAlat pencarian
LayoutrequestLayout, relayout5–30 msPerfetto, Systrace
DrawOverdraw, drawable berat3–20 msGPU Profiling
ThreadPemblokiran main thread10–200 msAndroid Studio Profiler
GCGarbage Collection5–15 msMemory Profiler
RenderingBeban GPU10–50 msGPU Tracer, Xcode GPU

Diagnosis Jank di Android

Di Android, diagnosis Jank dimulai dengan trace sistem Perfetto. Perfetto merekam aktivitas semua thread, CPU, GPU, dan penjadwal. Indikator jelas Jank adalah baris Choreographer.doFrame dan Choreographer.doCallbacks: jika interval antara dua panggilan doFrame berurutan melebihi 16.6 ms, bingkai terlewat. Perfetto menunjukkan penyebab pasti — system call, lock, atau GC mana yang menyebabkan keterlambatan. Di Android Studio Profiler, fungsionalitas serupa tersedia melalui CPU Profiler.

Untuk deteksi otomatis Jank di produksi, digunakan FrameMetricsAggregator — API yang mengumpulkan statistik per bingkai dan menggabungkannya per sesi. Di Android 12+, muncul PerformanceHintManager — API untuk petunjuk ke sistem tentang kecepatan bingkai target. Jika aplikasi menunjukkan bahwa ia bekerja dalam skenario 120 FPS, sistem dapat meningkatkan frekuensi CPU/GPU untuk mencegah Jank. Untuk logging sederhana semua bingkai yang terlewat, cukup berlangganan ke Choreographer.FrameCallback.

Logging Jank melalui Choreographer

Kode Kotlin berlangganan ke Choreographer.FrameCallback dan mencatat setiap bingkai yang terlewat dengan menyebutkan durasi keterlambatan. Callback dipanggil pada setiap VSync.

kotlin
class JankDetector {

    private val frameBudget = 16_666_666L
    private var previousFrameTime = 0L

    private val callback =
        Choreographer.FrameCallback { currentTime ->
            if (previousFrameTime != 0L) {
                val frameDuration =
                    currentTime - previousFrameTime
                val skippedFrames =
                    (frameDuration / frameBudget) - 1
                if (skippedFrames > 0) {
                    Log.w("Jank",
                        "$skippedFrames bingkai terlewat")
                }
            }
            previousFrameTime = currentTime
            Choreographer.getInstance()
                .postFrameCallback(this)
        }

    fun start() {
        Choreographer.getInstance()
            .postFrameCallback(callback)
    }
}

Diagnosis Jank di iOS

Di iOS, diagnosis Jank dilakukan melalui Instruments dengan templat Core Animation. Instruments menampilkan FPS real-time, jumlah render offscreen, dan hit-test. Indikator utama Jank di iOS: kolom merah di skala waktu Core Animation (melebihi anggaran bingkai), indikator Renderer tinggi (berarti offscreen rendering), dan FPS rendah. Untuk pemantauan produksi, MetricKit mengumpulkan laporan dengan metrik MXAnimatoryMetric, yang mencakup FPS rata-rata, P50 dan P95 waktu bingkai.

Diagnosis asli Jank di iOS mencakup CADisplayLink dengan pemeriksaan timestamp dan targetTimestamp. Jika timestamp saat ini tertinggal signifikan dari targetTimestamp, berarti satu atau lebih bingkai terlewat. Apple juga merekomendasikan penggunaan os_signpost untuk pembuatan profil kustom: tempatkan signpost-interval di awal dan akhir rendering bingkai dan periksa di Instruments interval mana yang melebihi 16.6 ms. Di SwiftUI, untuk diagnosis Jank digunakan UIView.invalidateIntrinsicContentSize — panggilan sering metode ini menunjukkan Layout yang tidak stabil.

CADisplayLink untuk deteksi Jank

Kode Swift mendeteksi bingkai yang terlewat melalui CADisplayLink. Jika selisih antara timestamp dan targetTimestamp melebihi 16.6 ms — Jank dicatat.

swift
class JankMonitor {

    private var displayLink: CADisplayLink?
    private var totalJank = 0

    func start() {
        displayLink = CADisplayLink(
            target: self,
            selector: #selector(detectJank)
        )
        displayLink?.add(to: .current,
            forMode: .common)
    }

    @objc
    private func detectJank() {
        guard let link = displayLink else { return }
        let delay = link.targetTimestamp
            - link.timestamp
        if delay > 0.0167 {
            totalJank += 1
        }
    }
}

Alat pembuatan profil Jank

Untuk pembuatan profil Jank, digunakan baik alat bawaan OS maupun SDK pihak ketiga. Di Android, alat kuncinya adalah Perfetto (menggantikan Systrace). Perfetto memungkinkan merekam trace hingga 30 detik dan menganalisisnya melalui antarmuka web ui.perfetto.dev. Ini menunjukkan garis waktu yang tepat dengan aktivitas Choreographer, thread rendering (RenderThread), dan GPU. Untuk analisis mendetail masalah GPU, digunakan AGI (Android GPU Inspector), yang menunjukkan tidak hanya waktu bingkai tetapi juga beban blok GPU spesifik — shader, rasterizer, blok tekstur.

Di iOS, padanannya adalah Instruments dengan templat Core Animation, Metal System Trace, dan GPU Driver. Core Animation menampilkan FPS dan waktu bingkai, Metal System Trace — kerja GPU dengan detail hingga setiap draw call. Untuk pembuatan profil di perangkat nyata di bawah beban, digunakan Firebase Performance (mengumpulkan metrik Screen Rendering) dan Sentry(menangkap stack trace saat Jank). API baru Android 15 Performance Hint memungkinkan pengembang menunjukkan ke sistem bingkai mana yang penting dan menerima peringatan dari sistem saat mendekati Jank.

FrameMetricsAggregator di produksi

Kode Kotlin menggunakan FrameMetricsAggregator untuk mengumpulkan statistik bingkai per sesi. Setelah menghentikan aggregator, jumlah bingkai yang terlewat ditampilkan.

kotlin
class JankAggregator(private val activity: Activity) {

    private val aggregator = FrameMetricsAggregator()

    fun startCollection() {
        aggregator.add(activity.window)
    }

    fun stopAndReport() {
        aggregator.remove()
        val result = aggregator.getMetrics()
        val totalFrames = result
            ?.get(FrameMetrics.TOTAL_DURATION)
            ?.size ?: 0
        val jankFrames = result
            ?.get(FrameMetrics.TOTAL_DURATION)
            ?.count { it > 16_666_666L} ?: 0
        Log.d("JankReport",
            "Rasio Jank: ${jankFrames * 100 / totalFrames}%")
    }
}

Metode mengatasi kegagapan bingkai

Mengatasi Jank memerlukan kombinasi metode tergantung tipenya. Untuk Layout Jank: mengganti hierarki dalam dengan ConstraintLayout/Compose/SwiftUI, menggunakan merge-tag, menghindari requestLayout dalam animasi. Untuk Draw Jank: menggunakan Debug GPU Overdraw untuk menemukan overdraw 4x+, mengganti drawable berat dengan vektor (VectorDrawable/PDF), menggunakan hardware layers dengan hati-hati — mempercepat rendering tetapi menggunakan lebih banyak memori GPU. Untuk Thread Jank: memindahkan semua operasi I/O, kerja database, dan dekode Bitmap ke thread latar belakang, menggunakan Kotlin Coroutines dengan Dispatcher yang tepat atau RxJava dengan Schedulers.io().

Untuk GC Jank: meminimalkan alokasi di onDraw() dan getView(), menggunakan object pool (ObjectPool), mengganti for-each dengan for berindeks, menggunakan immutable data class di Kotlin dengan copy() secara hati-hati — copy membuat objek baru. Untuk IPC Jank: inisialisasi malas ContentProvider melalui App Startup, memindahkan panggilan Binder ke thread latar belakang. Untuk Rendering Jank: mengurangi ukuran tekstur hingga resolusi maksimum layar, menggunakan kompresi ASTC atau ETC2, menghindari shader compilation yang tidak perlu (mengompilasi shader terlebih dahulu). Solusi komprehensif — menjalankan profil Perfetto/Instruments secara teratur di CI dan melacak regresi Jank.

Pola Anti-Jank: Async Layout

Kode Kotlin mendemonstrasikan pemuatan data asinkron ke layar setelah reportFullyDrawn, sehingga pekerjaan berat tidak memblokir bingkai pertama. Callback dipanggil setelah pengguna melihat antarmuka.

kotlin
class JankSafeLoader {

    suspend fun loadAfterFirstFrame(
        activity: Activity
    ) {
        // menjamin bahwa bingkai pertama sudah dirender
        if (Build.VERSION.SDK_INT >= 29) {
            activity.reportFullyDrawn()
        }

        // beban berat — setelah bingkai pertama
        withContext(Dispatchers.IO) {
            val data = fetchHeavyData()
            withContext(Dispatchers.Main) {
                updateUI(data)
            }
        }
    }
}

Pertanyaan yang sering diajukan

Apa itu Jank di aplikasi seluler?

Jank — adalah bingkai rendering yang terlewat yang muncul sebagai kegagapan atau sentakan animasi yang terlihat. Terjadi ketika waktu persiapan bingkai melebihi anggaran waktu (16.6 ms untuk 60 FPS).

Apa penyebab utama Jank?

Layout Jank (sering requestLayout), Draw Jank (overdraw), Thread Jank (pemblokiran main thread), GC Jank (garbage collection), IPC Jank (panggilan Binder), dan Rendering Jank (shader berat).

Bagaimana mendiagnosis Jank di Android?

Gunakan Perfetto untuk trace sistem, GPU Profiling untuk analisis fase bingkai, dan FrameMetricsAggregator untuk pemantauan produksi. Di Android Studio — CPU Profiler dengan Deep Java Trace.

Bagaimana mengukur Jank di iOS?

Melalui Instruments dengan templat Core Animation atau Metal System Trace. Untuk produksi — MetricKit dengan MXAnimatoryMetric. Secara terprogram — CADisplayLink dengan memeriksa selisih timestamp dan targetTimestamp.

Berapa persentase Jank yang dianggap kritis?

Menurut Google, indikator Jank lebih dari 3% sesi scroll (3 dari 100 scroll mengandung kegagapan) menyebabkan peningkatan ulasan negatif sebesar 22%. Indikator target — kurang dari 0.5% sesi scroll.

Ringkasan

  • Jank — bingkai yang terlewat menyebabkan kegagapan animasi yang terlihat di aplikasi seluler.
  • Penyebab utama: Layout Jank, Draw Jank, Thread Jank, GC Jank, IPC Jank, dan Rendering Jank.
  • Diagnosis Jank di Android — melalui Perfetto, GPU Profiling, dan FrameMetricsAggregator.
  • Diagnosis Jank di iOS — melalui Instruments, CADisplayLink, dan MetricKit.
  • Mengatasi Jank memerlukan kombinasi: hierarki datar, thread latar belakang, alokasi minimal, caching.
  • Indikator target Jank — kurang dari 0.5% sesi scroll dengan kegagapan.
  • Profil teratur di CI mencegah regresi kinerja sebelum masuk ke produksi.

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.

Diskusikan proyek

Baca juga