Kerangka kerja Flutter berfungsi dengan baik dan cepat secara default, tetapi apakah itu berarti Anda tidak perlu memikirkan kinerja sama sekali? Tidak. Benar-benar nyata untuk menulis aplikasi Flutter yang akan lambat. Di sisi lain, Anda juga dapat menggunakan kerangka kerja secara maksimal dan membuat aplikasi Anda tidak hanya cepat, tetapi juga efisien, menghabiskan lebih sedikit waktu prosesor dan baterai.

Inilah yang ingin kami lihat: hasil yang signifikan secara statistik dari membandingkan dua versi aplikasi Anda dengan beberapa metrik yang signifikan. Baca terus untuk mengetahui caranya.
Ada beberapa panduan umum untuk mengoptimalkan kinerja di Flutter:
- Libatkan sesedikit mungkin widget saat memperbarui status.
- Perbarui status hanya bila perlu.
- Mengambil tugas-tugas intensif komputasi dari metode
build
Anda dan idealnya dari isolate utama.
Kebenaran yang menyedihkan adalah bahwa untuk banyak pertanyaan tentang mengoptimalkan kinerja, jawabannya adalah "betapa beruntungnya". Apakah pengoptimalan khusus ini sepadan dengan usaha dan biaya perawatan untuk widget khusus ini? Apakah pendekatan khusus ini masuk akal dalam situasi khusus ini?
Satu-satunya jawaban yang berguna untuk pertanyaan-pertanyaan ini adalah pengujian dan pengukuran. Hitung bagaimana setiap pilihan memengaruhi kinerja dan membuat keputusan berdasarkan data ini.
Berita baiknya adalah Flutter menyediakan alat profil kinerja hebat seperti Dart DevTools (saat ini dalam rilis pratinjau), yang mencakup Flutter Inspector, atau Anda dapat menggunakan Flutter Inspector langsung dari Android Studio (dengan plugin Flutter terpasang). Anda memiliki Flutter Driver
untuk menguji aplikasi Anda dan Profile mode
untuk menyimpan informasi kinerja.
Berita buruknya adalah smartphone modern terlalu pintar.
Masalah dengan regulator
Mengukur kinerja aplikasi Flutter sangat sulit untuk pengontrol iOS dan Android. Daemon tingkat sistem ini mengontrol kecepatan prosesor pusat dan grafik tergantung pada beban. Tentu saja, pada dasarnya ini bagus, karena memberikan operasi yang lancar dengan konsumsi baterai yang lebih sedikit.
Kerugiannya adalah Anda dapat membuat aplikasi Anda jauh lebih cepat dengan meningkatkan jumlah pekerjaan yang dilakukan.
Di bawah ini Anda dapat melihat bagaimana menambahkan siklus panggilan cetak yang tidak berarti ke aplikasi membuat regulator mengalihkan CPU ke frekuensi yang meningkat, yang membuat aplikasi lebih cepat dan kinerjanya lebih mudah diprediksi.

Masalah dengan regulator: secara default, Anda tidak bisa mempercayai angka Anda. Dalam diagram rentang ini, kami memiliki proses terpisah pada sumbu x (ditandai dengan waktu yang tepat mereka mulai) dan membangun waktu pada sumbu Y. Seperti yang Anda lihat, ketika kami memperkenalkan beberapa pernyataan cetak yang sama sekali tidak perlu, ini mengarah pada fakta bahwa waktu pembuatan turun tapi tidak sampai.
Dalam percobaan ini, kode terburuk menghasilkan waktu pembuatan lebih cepat (lihat di atas), waktu rasterisasi lebih cepat, dan laju bingkai lebih tinggi. Ketika kode yang secara objektif lebih buruk mengarah pada peningkatan indikator kinerja, Anda tidak dapat mengandalkan indikator ini sebagai panduan (rekomendasi).
Ini hanyalah salah satu contoh bagaimana pengujian kinerja aplikasi seluler dapat menjadi tidak intuitif dan kompleks.
Di bawah ini, saya membagikan beberapa tips yang saya kumpulkan ketika mengerjakan aplikasi Quest Pengembang Flutter untuk Google I / O.
Kiat umum
- Jangan mengukur kinerja dalam mode debug (
DEBUG mode
). Ukur kinerja hanya dalam Profile mode
profil. - Ukur di perangkat nyata, bukan di iOS Simulator atau Android Emulator. Emulator perangkat lunak sangat bagus untuk pengembangan, tetapi memiliki karakteristik kinerja yang berbeda dari yang asli. Flutter tidak akan memungkinkan Anda bekerja dalam mode profil pada perangkat yang disimulasikan, karena itu tidak masuk akal. Data yang Anda kumpulkan dengan cara ini tidak berlaku untuk kinerja nyata.
- Idealnya menggunakan perangkat fisik yang sama persis. Jadikan perangkat pengujian kinerja khusus Anda dan jangan pernah menggunakannya untuk hal lain.
- Jelajahi Alat Profil Performa Bergetar .
Regulator CPU / GPU
Seperti dibahas di atas, sistem operasi modern mengubah frekuensi setiap prosesor dan GPU yang mereka inginkan sesuai dengan beban dan beberapa heuristik lainnya. (Misalnya, menyentuh layar biasanya akan meningkatkan kecepatan ponsel Android Anda.)
Di Android, Anda dapat menonaktifkan kontrol ini. Kami menyebut proses ini "kunci penskalaan".
- Buat skrip yang menonaktifkan kontrol pada perangkat Anda untuk menguji kinerja. Anda dapat menggunakan contoh Skia untuk inspirasi. Anda juga dapat melihat Unix CPU API .
- Anda mungkin menginginkan sesuatu yang kurang fleksibel dan lebih ringan jika Anda tidak melakukan pengujian sebanyak Skia. Lihat skrip shell di Quest Developer untuk melihat ke mana harus pergi. Sebagai contoh, bagian selanjutnya dari skrip mengatur CPU untuk pengontrol userspace (satu-satunya pengontrol yang tidak mengubah frekuensi prosesor itu sendiri).
- Tujuan Anda di sini bukan untuk mensimulasikan kinerja nyata (pengguna tidak mematikan regulator pada perangkat mereka), tetapi untuk memiliki indikator kinerja yang sebanding antara mulai.
- Pada akhirnya, Anda perlu bereksperimen dan mengadaptasi skrip shell ke perangkat yang akan Anda gunakan. Ini berfungsi, tetapi sampai Anda melakukan ini, data kinerja Anda akan menipu Anda.

Versi awal dari Quest Developer, diuji dengan Flutter Driver di desktop saya.
Driver bergetar
Flutter Driver memungkinkan Anda menguji aplikasi Anda secara otomatis. Baca bagian "Performance Profileing " di flutter.dev untuk mengetahui bagaimana menggunakannya ketika membuat profil aplikasi Anda.
- Untuk menguji kinerja, jangan menguji aplikasi Anda secara manual. Selalu gunakan Flutter Driver untuk mendapatkan data yang benar-benar indikatif.
- Tulis kode Flutter Driver Anda sehingga memeriksa apa yang benar-benar ingin Anda ukur. Jika Anda membutuhkan kinerja aplikasi secara keseluruhan, cobalah menelusuri semua bagian aplikasi dan lakukan apa yang akan dilakukan pengguna.
- Jika aplikasi Anda memiliki elemen keacakan (
Random
, acara jaringan, dll.), Lalu buat "tiruan" untuk situasi seperti itu. Uji coba harus sedekat mungkin satu sama lain. - Jika mau, Anda bisa menambahkan acara khusus ke timeline menggunakan metode
startSync()
dan finishSync()
dari kelas Timeline . Ini dapat bermanfaat jika Anda tertarik dengan kinerja fungsi tertentu. Letakkan startSync()
di awal dan finishSync()
di ujungnya. - Simpan ringkasan ( writeSummaryToFile ) dan, yang lebih penting, timeline mentah ( writeTimelineToFile ).
- Uji setiap versi aplikasi Anda berkali-kali. Untuk Quest Developer, saya menghabiskan 100 awal. (Ketika Anda mengukur hal-hal yang mungkin berisik, seperti menggunakan metrik p99, Anda mungkin perlu lebih banyak menjalankan.) Untuk sistem berbasis POSIX, ini berarti melakukan sesuatu seperti berikut ini:
for i in {1..100}; do flutter drive --target=test_driver/perf.dart --profile; done
for i in {1..100}; do flutter drive --target=test_driver/perf.dart --profile; done
for i in {1..100}; do flutter drive --target=test_driver/perf.dart --profile; done

Alat waktu Chrome untuk memeriksa hasil profil di Flutter.
Garis waktu
Timeline adalah output mentah dari hasil profil Anda. Flutter menulis informasi ini ke file JSON, yang dapat diunduh dalam chrome://tracing
.
- Pahami cara membuka timeline lengkap di Chrome. Anda cukup membuka
chrome://tracing
di browser Chrome, klik “Load” dan pilih file JSON. Anda dapat membaca lebih lanjut di panduan singkat ini . (Ada juga alat timeline Flutter yang saat ini dalam pratinjau teknologi. Saya tidak menggunakannya karena proyek Pengembang Quest diluncurkan sebelum alat Flutter siap.) - Gunakan tombol WSAD untuk menavigasi timeline di
chrome://tracing
dan 1234 untuk mengubah mode operasi. - Saat mengatur pengujian kinerja untuk pertama kalinya, pertimbangkan untuk menjalankan Flutter Driver dengan alat Systrace Android. Ini memberi Anda ide yang lebih baik tentang apa yang sebenarnya terjadi di perangkat, termasuk informasi tentang penskalaan frekuensi prosesor. Jangan mengukur keseluruhan aplikasi dengan Systrace, karena ini akan membuat semuanya lebih lambat dan kurang dapat diprediksi.
- Bagaimana menjalankan Android Systrace dengan Flutter Driver? Pertama, luncurkan Android Systrace dengan
/path/to/your/android/sdk/platform-tools/systrace/systrace.py --atrace-categories=gfx,input,view,webview,wm,am,sm,audio,video,camera,hal,app,res,dalvik,rs,bionic,power,pm,ss,database,network,adb,pdx,sched,irq,freq,idle,disk,load,workq,memreclaim,regulators,binder_driver,binder_lock
. Kemudian flutter run test_driver/perf.dart --profile --trace-systrace
aplikasi flutter run test_driver/perf.dart --profile --trace-systrace
. Terakhir, jalankan Flutter Driver flutter drive --driver=test_driver/perf_test.dart --use-existing-app=http://127.0.0.1:NNNNN/
(di mana NNNNN adalah port yang memberi Anda aplikasi flutter di atas).
Metrik
Lebih baik untuk melihat sebanyak mungkin metrik, tetapi saya memutuskan bahwa beberapa lebih berguna daripada yang lain.
Waktu pembuatan dan waktu rasterisasi (metrik yang disediakan secara default menggunakan TimelineSummary
) hanya berguna untuk pengujian kinerja yang sangat sulit, yang tidak mencakup banyak hal selain membuat antarmuka pengguna.
Jangan menganggap TimelineSummary.frameCount
sebagai cara untuk menghitung frame per detik (FPS). Alat profil flutter tidak memberikan informasi kecepatan bingkai nyata. TimelineSummary
menyediakan metode countFrames()
, tetapi hanya menghitung jumlah rakitan bingkai yang diselesaikan. Aplikasi yang dioptimalkan dengan baik yang membatasi pembangunan kembali yang tidak perlu (pembaruan) akan memiliki FPS lebih rendah daripada aplikasi yang tidak dioptimalkan yang sering membangun kembali.
Secara pribadi, saya mendapatkan data yang paling berguna dengan mengukur total waktu prosesor yang dihabiskan untuk mengeksekusi kode Dart. Ini menghitung kode yang dieksekusi dalam metode build
Anda dan di luarnya. Dengan asumsi Anda menjalankan tes profil pada perangkat yang dikunci skala, total waktu CPU dapat dianggap perkiraan yang baik untuk berapa banyak baterai yang akan dikonsumsi aplikasi Anda.

Cara termudah untuk mengetahui total waktu prosesor yang dihabiskan untuk mengeksekusi kode Dart adalah memperkirakan jumlah event MessageLoop:FlushTasks
pada timeline. Untuk Pengembang Quest, saya menulis alat Dart untuk mengekstraknya.
Untuk menemukan sampah (tempat sampah) (yaitu, bingkai yang dijatuhkan), cari yang ekstrem. Misalnya, untuk kasus tertentu dari Quest Pengembang dan perangkat yang kami uji, penting untuk melihat waktu pembuatan dari persentil ke-95. (Waktu pembuatan dari persentil ke-90 terlalu mirip, bahkan jika Anda membandingkan kode dengan tingkat kinerja yang sangat berbeda, dan angka-angka dari persentil ke-99 biasanya berisik. Kinerja Anda mungkin beragam.)

Seperti disebutkan di atas, uji setiap versi aplikasi Anda beberapa (mungkin 100) kali. Kemudian gunakan data rata-rata atau persentil dengan bidang kesalahan. Lebih baik lagi, gunakan grafik rentang.
Hasil
Setelah menyetel, Anda dapat dengan percaya diri membandingkan komitmen dan melakukan eksperimen. Di bawah ini Anda dapat melihat jawaban untuk dilema umum: "apakah optimalisasi biaya perawatan ini sepadan?"

Saya pikir dalam kasus khusus ini jawabannya adalah ya. Berkat hanya beberapa baris kode, setiap bagian otomatis dari aplikasi kami membutuhkan waktu CPU rata-rata 12% lebih sedikit.
Tapi - dan ini adalah pesan utama artikel ini - pengukuran optimasi lain mungkin menunjukkan sesuatu yang sama sekali berbeda. Menggoda tetapi salah untuk mencoba mengekstrapolasi pengukuran kinerja terlalu luas.
Dengan kata lain: "betapa beruntungnya." Dan kita harus tahan dengan itu.