Cara Optimasi Performa Aplikasi Flutter yang Lemot di HP Murah

Panduan praktis mempercepat aplikasi Flutter: mengukur di profile mode pada HP Android kelas bawah, membaca frame chart di DevTools, Impeller, mengurangi rebuild, list panjang, memori gambar, isolate, waktu startup, dan ukuran APK.

Dipublikasikan 10 menit baca
Beberapa HP Android dan iPhone berjajar di meja untuk pengujian aplikasi

Keluhannya hampir selalu sama. Di iPhone milik developer aplikasinya mulus, tapi di HP Android sejutaan yang dipakai sebagian besar pengguna, scroll-nya patah-patah dan layar pertama baru muncul setelah empat detik. Flutter sebenarnya cukup cepat untuk hampir semua aplikasi bisnis. Kalau terasa lemot, penyebabnya biasanya ada di beberapa tempat yang itu-itu saja, dan bisa ketemu dalam satu sore asal cara mengukurnya benar. Berikut proses yang kami pakai.

Ukur di Profile Mode, Pakai HP Murah

Jangan pernah menilai performa dari debug mode. Build debug menjalankan Dart dengan JIT compiler dan banyak assertion tambahan, jadi bisa beberapa kali lebih lambat dari release. Jalankan flutter run --profile. Mode ini dikompilasi AOT seperti release, tapi tetap menyediakan hook yang dibutuhkan DevTools. Tes di device asli, dan pilih yang lambat. HP Android entry-level dengan RAM 3 atau 4 GB jauh lebih jujur daripada HP flagship atau emulator. Emulator jalan di atas CPU laptop, jadi bisa menyembunyikan masalah atau malah memunculkan masalah yang tidak ada di HP sungguhan. Sediakan satu HP murah di kantor khusus untuk keperluan ini.

Baca Frame Chart di DevTools

Di layar 60 Hz, setiap frame punya jatah sekitar 16 ms. Di layar 120 Hz jatahnya tinggal sekitar 8 ms. Buka tab Performance di Flutter DevTools dan lihat frame chart-nya. Setiap frame punya dua batang. Batang UI thread berisi kode Dart Anda: build, layout, dan apa pun yang jalan di main isolate. Batang raster thread berisi proses mengubah layer tree menjadi perintah GPU. Kalau batang UI melewati jatah, berarti terlalu banyak yang di-build atau ada pekerjaan berat di Dart. Kalau batang raster yang lewat, berarti ada yang mahal untuk digambar. Biasanya Opacity atau ShaderMask yang memicu saveLayer, clip yang menumpuk, shadow besar dengan blur, atau gambar raksasa. Nyalakan Track Widget Builds untuk melihat widget mana yang di-rebuild di frame yang jank, lalu cek jumlah rebuild di Inspector untuk menemukan widget yang di-rebuild ratusan kali.

Impeller Sudah Membereskan Jank Shader

Dulu jank paling parah di Flutter datang dari shader yang dikompilasi saat animasi pertama kali jalan. Impeller, engine rendering yang lebih baru, mengompilasi shader-nya saat build, jadi patah-patah di pemakaian pertama itu sebagian besar sudah hilang. Impeller jadi default di iOS sejak Flutter 3.10 dan di kebanyakan device Android modern sejak Flutter 3.27. Trik warm-up SkSL yang dulu sering dipakai sudah tidak perlu. GPU Android yang lebih tua atau yang kurang umum masih bisa berperilaku lain, jadi tetap sertakan minimal satu HP lama saat testing. Kalau ada glitch tampilan, bandingkan dengan Impeller dimatikan untuk keperluan lapor bug, tapi jangan jadikan itu solusi di rilis.

Berhenti Me-rebuild yang Tidak Berubah

  • setState di bagian atas layar yang besar akan me-rebuild seluruh layar. Turunkan state ke widget kecil yang memang berubah.
  • Pecah build method yang panjang menjadi class widget terpisah, jangan helper method. Flutter bisa melewati widget yang konfigurasinya tidak berubah, tapi tidak bisa melewati pemanggilan method.
  • Tambahkan const di constructor di mana pun analyzer mengizinkan. Widget const selalu instance yang sama, jadi Flutter tidak perlu me-rebuild-nya.
  • Oper subtree yang statis lewat parameter child di AnimatedBuilder dan builder sejenis, supaya cukup dibangun sekali dan tidak ikut dibangun ulang di setiap tick animasi.
  • Jangan membuat Future di dalam build, misalnya FutureBuilder(future: fetchOrders()). Setiap rebuild akan menembak request baru. Buat sekali saja di initState atau di layer state.
  • Dengarkan potongan state sekecil mungkin. Caranya dengan Riverpod dan Bloc sudah kami bahas di artikel state management Flutter.

List yang Panjang

ListView dengan daftar children akan membangun semua item di awal. Kalau ada 500 baris pesanan, berarti 500 widget dibangun sebelum frame pertama tampil. ListView.builder hanya membangun item yang terlihat di layar plus sedikit cadangan. Kalau tinggi semua baris sama, isi itemExtent atau prototypeItem supaya Flutter tidak perlu mengukur tiap baris saat scroll. Hindari ListView dengan shrinkWrap: true di dalam Column atau scroll view lain. Pengaturan ini memaksa semua item di-layout dan diam-diam menghilangkan manfaat lazy loading. Pakai CustomScrollView dengan sliver, dan ambil data dari API per halaman, 20 sampai 50 item sekali ambil.

Gambar Itu Boros Memori

Foto 4000 x 3000 dari kamera HP akan memakan sekitar 48 MB memori setelah di-decode, walaupun hanya ditampilkan sebagai thumbnail 100 piksel. Grid berisi foto-foto seperti itu bisa bikin HP murah crash. Isi cacheWidth atau cacheHeight di widget Image supaya gambar di-decode sesuai ukuran tampilnya. Ingat, nilai ini dalam piksel fisik, jadi kalikan ukuran logis dengan device pixel ratio. Kalau pakai cached_network_image, gunakan memCacheWidth untuk efek yang sama. Lebih bagus lagi kalau backend menyediakan thumbnail yang sudah diperkecil. Selama development, set debugInvertOversizedImages ke true, dan Flutter akan menampilkan gambar yang kebesaran dengan warna terbalik supaya gampang ketahuan.

Pindahkan Pekerjaan Berat dari UI Isolate

Kode Dart Anda jalan di satu thread per isolate. Parsing response JSON 2 MB bisa makan lebih dari 100 ms di HP kelas bawah, dan selama itu tidak ada frame yang digambar. Isolate.run, yang tersedia sejak Dart 2.19, menjalankan fungsi di isolate latar belakang yang berumur pendek lalu mengembalikan hasilnya. Fungsi compute yang lebih lama melakukan hal serupa. Membuat isolate dan menyalin data bolak-balik butuh beberapa milidetik, jadi pakai untuk pekerjaan yang lebih lama dari satu frame, seperti parsing JSON besar, olah gambar, enkripsi, atau membuat PDF. Di Flutter web, isolate tidak tersedia dan compute tetap jalan di thread yang sama.

Waktu Startup dan Ukuran Aplikasi

Startup yang lambat biasanya ulah sendiri. Fungsi main yang umum kami temui menunggu Firebase, remote config, analytics, database lokal, dan refresh token sebelum memanggil runApp. Inisialisasi hanya yang dibutuhkan layar pertama, sisanya jalankan setelah frame pertama tampil. Ukur dengan flutter run --profile --trace-startup, yang menulis waktu sampai frame pertama ke file start_up_info.json. Untuk ukuran, rilis dalam format Android App Bundle supaya Google Play hanya mengirim kode untuk arsitektur CPU masing-masing HP, atau pakai --split-per-abi kalau Anda membagikan APK langsung. Jalankan flutter build appbundle --analyze-size untuk melihat apa yang paling makan tempat. Biasanya pelakunya font yang tidak dipakai, aset PNG yang belum dikompres, dan package yang besar. Build dengan --obfuscate dan --split-debug-info juga memangkas sedikit ukuran dan tetap menyimpan simbol untuk membaca crash report.

Gejala, Penyebab, dan Perbaikannya

GejalaKemungkinan penyebabPerbaikan
Scroll list panjang patah-patahListView dengan children, atau shrinkWrap di dalam scroll view lainListView.builder atau sliver, plus itemExtent kalau tinggi baris tetap
Mengetik di text field terasa telatsetState di posisi atas me-rebuild seluruh formTurunkan state ke widget field, pakai const dan widget yang lebih kecil
Aplikasi crash atau restart di layar penuh gambarFoto ukuran penuh di-decode untuk thumbnail kecilcacheWidth atau memCacheWidth, thumbnail dari server
UI diam sesaat setelah memanggil APIJSON besar di-parse di UI isolateIsolate.run atau compute, perkecil response API
Batang raster merah saat animasiOpacity, clip, blur, atau shadow besar yang memicu saveLayerFadeTransition atau AnimatedOpacity, efek yang lebih sederhana, RepaintBoundary di bagian yang beranimasi
Layar kosong beberapa detik saat dibukaTerlalu banyak await di main sebelum runAppInisialisasi belakangan, setelah frame pertama

Checklist Sebelum Setiap Rilis

  1. 1Build di profile mode dan tes lima layar yang paling sering dipakai di HP paling lambat yang Anda dukung.
  2. 2Scroll cepat setiap list panjang sambil memperhatikan frame merah di frame chart.
  3. 3Jalankan sekali dengan debugInvertOversizedImages dan perbaiki gambar yang warnanya terbalik.
  4. 4Cek waktu startup dengan --trace-startup dan bandingkan dengan rilis sebelumnya.
  5. 5Jalankan --analyze-size dan cari bagian yang membengkak lebih dari satu megabyte.
  6. 6Lihat laporan crash dan ANR di Firebase Crashlytics atau Play Console, terutama error kehabisan memori.

Jangan mengoptimasi sesuatu yang belum diukur. Seringnya, bagian yang lambat bukan di tempat yang tim kira.

Sebagian besar perbaikan di atas sebenarnya kecil, asal tahu harus mencari di mana. Training Flutter kami untuk tim punya sesi praktik ketika peserta mem-profile aplikasi yang sengaja dibuat lambat memakai DevTools lalu memperbaikinya selangkah demi selangkah. Biasanya setelah sesi itu cara mereka menulis widget ikut berubah.

Poin penting

  • Ukur di profile mode pada HP Android kelas bawah yang asli, jangan di debug mode atau hanya di emulator.
  • Pakai frame chart DevTools untuk membedakan masalah UI thread dan raster thread sebelum mengubah kode.
  • Kurangi rebuild dengan class widget yang lebih kecil, constructor const, dan state yang ditaruh dekat dengan pemakainya.
  • Pakai ListView.builder untuk list panjang dan decode gambar sesuai ukuran tampil dengan cacheWidth.
  • Pindahkan parsing dan pekerjaan berat ke Isolate.run, dan jaga main tetap ringan supaya frame pertama cepat muncul.
Bagikan artikel ini

Artikel terkait

Artikel lain tentang software development, AI, cloud, dan infrastruktur.

Smartphone dengan wireframe aplikasi di samping buku catatan dan kalkulator di atas mejaPengembangan Software

10 menit baca

Berapa Biaya Pembuatan Aplikasi Mobile di Indonesia?

Kisaran harga indikatif dalam Rupiah untuk aplikasi mobile sederhana, menengah, dan kompleks, faktor yang benar-benar menentukan harga, Flutter versus dua aplikasi native, tim dan durasi, biaya tahunan setelah rilis, serta cara membandingkan penawaran vendor.

Orang memegang HP Android yang sedang membuka website dengan koneksi selulerPengembangan Web

9 menit baca

Cara Mempercepat Loading Website Bisnis: Panduan Core Web Vitals

Panduan praktis mempercepat website: kenapa kecepatan penting di HP Android kelas menengah dan jaringan seluler Indonesia, arti LCP, INP, dan CLS, beda data lab dan data lapangan, penyebab website lambat, cara memperbaikinya, dan langkah kerjanya.

Mari berdiskusi

Sedang mencari partner untuk pengembangan software?

Ceritakan proyek yang sedang Anda bangun, kebutuhan yang ingin diselesaikan, dan tantangan yang dihadapi. Kami dapat membantu membahas pendekatan teknis, scope, timeline, dan estimasi biaya.

Mulai diskusi