Aplikasi macOS yang dibangun dengan SwiftUI kerap terasa lambat ketika daftar data panjang, banyak jendela terbuka, atau animasi berjalan terus-menerus. Optimasi performa aplikasi macOS dengan SwiftUI berbeda dari iOS karena layar lebih luas dan memori lebih longgar, tapi pengguna desktop menuntut respons instan terhadap klik dan scroll. Berikut tujuh cara yang bisa diterapkan sesuai kebutuhan.
1. Pakai List dengan identifier yang stabil
Pada macOS, List dan ScrollView dengan LazyVStack hanya menghemat render jika setiap baris punya identitas yang konsisten. Gunakan id dari model data, bukan indeks array.
List(items, id: .id) { item in
RowView(item: item)
}
Ketika pengguna menggulir dan urutan data berubah, SwiftUI bisa mempertahankan view yang sudah ada. Tanpa identifier stabil, sel akan dibangun ulang dan animasi diff menjadi mahal. Untuk dataset besar, pertimbangkan Table yang memang dirancang untuk kolom dan seleksi di macOS.
2. Batasi pemakaian GeometryReader
GeometryReader memaksa SwiftUI menghitung ukuran setiap kali layout berubah. Di jendela macOS yang bisa di-resize bebas, dampaknya terasa saat pengguna menyeret sudut jendela. Jika hanya butuh lebar atau tinggi, pakai containerRelativeFrame atau onGeometryChange yang lebih terarah. Simpan hasil pengukuran di state dan hindari memanggil GeometryReader di dalam baris list.
3. Pisahkan state yang sering berubah dari view besar
View yang membaca banyak @State atau @ObservedObject akan dievaluasi ulang setiap kali salah satu nilai berubah. Pecah view menjadi komponen kecil yang hanya bergantung pada data yang relevan. Untuk pengaturan aplikasi, strategi penyimpanan yang tepat ikut memengaruhi seberapa sering view perlu membaca ulang nilai; panduan menyimpan data pengaturan di aplikasi iOS dan macOS membahas pilihan itu lebih jauh.
4. Turunkan frekuensi pembaruan saat scroll
Derived state seperti pencarian, filter, dan formatting tanggal sebaiknya tidak dihitung di setiap frame. Gunakan .task(id:) dengan debounce, atau simpan hasil perhitungan di cache. Format tanggal yang dipanggil berulang untuk setiap baris juga membebani CPU; panduan format tanggal dan angka di Swift membantu memilih formatter yang di-cache alih-alih dibuat ulang.
5. Kelola jendela dan scene dengan disiplin
Setiap WindowGroup yang terbuka menjalankan view tree-nya sendiri. Aplikasi yang membuka banyak jendela dokumen tanpa menutup observer atau timer akan menumpuk beban. Gunakan @Environment(.scenePhase) untuk menghentikan pembaruan saat jendela tidak aktif, dan lepaskan resource di onDisappear. Untuk melacak sisa memori setelah jendela ditutup, teknik di panduan debugging memori Swift bisa dipakai memeriksa retain cycle pada closure yang menahan view model.
6. Pilih animasi yang murah
Animasi dengan withAnimation pada perubahan layout yang kompleks memicu perhitungan ulang seluruh subtree. Di macOS, animasi opacity dan offset jauh lebih murah daripada animasi ukuran frame pada container besar. Matikan animasi saat pengguna mengaktifkan Reduce Motion lewat @Environment(.accessibilityReduceMotion). Jika animasi melibatkan banyak elemen, pertimbangkan memindahkannya ke layer Core Animation terpisah dan bandingkan dengan pendekatan di perbandingan animasi SwiftUI vs UIKit.
7. Ukur dengan Instruments, bukan asumsi
Sebelum mengubah arsitektur, rekam profil aplikasi memakai Instruments. Template Time Profiler menunjukkan fungsi yang menyita CPU, sementara Allocations dan Leaks memperlihatkan pertumbuhan memori. Untuk aplikasi yang berkomunikasi dengan server, ukur juga waktu tunggu jaringan secara berkala agar tidak tertukar dengan render lambat; metode uji latensi jaringan secara berkala menjelaskan cara memantaunya. Jika aplikasi menyimpan data pengguna, pastikan juga tidak ada kebocoran kredensial dengan memeriksa cara memeriksa kebocoran data pribadi dan mengatasinya.
Urutan prioritas yang masuk akal
- Profil dulu, catat baseline waktu render dan memori.
- Perbaiki identifier list dan view yang terlalu besar.
- Kurangi GeometryReader dan animasi mahal.
- Baru pertimbangkan perubahan arsitektur state.
Ketujuh langkah di atas saling melengkapi. Perbaikan pada list dan state biasanya memberi hasil paling terasa, sementara animasi dan jendela perlu perhatian setelah struktur view stabil. Ukur ulang setiap perubahan agar tidak menambah kompleksitas tanpa manfaat.
Pertanyaan yang Sering Diajukan
Apakah SwiftUI cukup cepat untuk aplikasi macOS dengan tabel besar?
Untuk tabel berisi ribuan baris, Table dengan kolom eksplisit lebih hemat daripada List kustom. Jika performa masih kurang, pertimbangkan NSTableView lewat representable dan bandingkan hasilnya dengan Instruments.
Kapan sebaiknya memakai Instruments dibanding preview di Xcode?
Preview Xcode berguna untuk melihat layout, tapi tidak menunjukkan biaya CPU dan memori. Instruments dipakai saat aplikasi mulai terasa lambat atau sebelum rilis, dengan skenario penggunaan yang realistis.
Apakah mengurangi animasi selalu meningkatkan performa?
Tidak selalu. Animasi opacity dan transformasi sederhana murah, sedangkan animasi layout pada subtree besar yang mahal. Ukur dampaknya sebelum menghapus animasi yang penting untuk umpan balik pengguna.
More Stories
Membuat Aplikasi macOS dengan SwiftUI: Langkah demi Langkah