Dart sudah cukup cepat untuk hampir semua kebutuhan aplikasi: UI, state, jaringan, penyimpanan. Tapi ada beberapa pekerjaan yang membuatnya kewalahan, dan dua di antaranya sering saya temui: mengolah gambar dan mengolah suara.
Untuk dua hal itu saya menulis plugin dengan inti Rust: ironpress untuk kompresi gambar dan flutter_audio_fx untuk efek suara real-time. Ini beberapa hal yang saya pelajari.
Tanda-tanda butuh Rust
- Kerjanya berat di CPU dan berulang. Mengompres puluhan foto sebelum diunggah, atau memproses audio ribuan kali per detik.
- Library terbaiknya sudah ada di dunia native. mozjpeg, oxipng, dan libwebp jauh lebih matang daripada implementasi Dart mana pun.
- Waktu itu penting. Pada audio, terlambat sedikit saja langsung terdengar sebagai bunyi kresek.
Kalau tidak ada satu pun tanda itu, tetap di Dart. Menambah Rust berarti menambah toolchain, build, dan hal yang bisa rusak.
Jumlah panggilan lebih penting daripada kecepatan
Pelajaran terbesar dari ironpress: memanggil fungsi native lewat FFI itu murah, tapi bolak-balik antara Dart dan Rust tetap ada ongkosnya. Contohnya fitur "kompres sampai ukuran file maksimal sekian KB". Cara naifnya adalah mencoba kualitas di Dart, memanggil Rust, mengecek ukuran, lalu mengulang. Di ironpress, seluruh pencarian kualitasnya berjalan di dalam Rust, jadi Dart cukup memanggil sekali.
Untuk batch, saya pilih jalan tengah: Dart membagi pekerjaan per kelompok, lalu setiap kelompok diproses paralel di Rust. Hasilnya, progress dan pembatalan tetap bisa dikendalikan dari Dart dengan rapi, sementara pekerjaan beratnya tetap di native.
Di audio, aturannya lebih keras
flutter_audio_fx punya 14 efek, dari pitch shift dan auto-tune sampai peredam bising dan reverb. Aturan utamanya: tidak boleh ada alokasi memori di thread audio. Semua buffer disiapkan di depan, karena satu alokasi yang lambat di waktu yang salah langsung terdengar.
Rust sangat membantu di sini. Batasan seperti itu lebih mudah dijaga ketika compiler ikut mengawasi kepemilikan memori.
Jangan bebani pemakai plugin
Plugin dengan inti Rust tidak boleh memaksa pemakainya memasang Rust. Kedua plugin saya mengirim library native yang sudah dikompilasi untuk setiap platform, jadi bagi pemakainya rasanya sama seperti plugin Flutter biasa. Repot menyiapkan build untuk Android, iOS, Windows, macOS, dan Linux cukup ditanggung sekali oleh pembuatnya, bukan oleh setiap pemakai.
Ringkasnya
- Pakai Rust untuk pekerjaan berat di CPU, bukan untuk semuanya.
- Kurangi bolak-balik lewat FFI: kirim pekerjaan sebesar mungkin dalam satu panggilan.
- API untuk pemakai tetap terasa Dart:
Future, progress, pembatalan. - Kirim library yang sudah dikompilasi supaya pemakai tidak perlu memasang toolchain apa pun.
Kode keduanya terbuka di GitHub. Kalau kamu sedang mempertimbangkan Rust untuk aplikasi Flutter, saya senang diajak diskusi.