Dokumen ini membantu Anda mengidentifikasi dan mengatasi masalah performa utama di aplikasi.
Masalah performa utama
Ada banyak masalah yang dapat menyebabkan performa buruk di aplikasi, tetapi berikut adalah beberapa masalah umum yang harus diperhatikan di aplikasi Anda:
- Latensi pengaktifan
Latensi pengaktifan adalah jumlah waktu yang dibutuhkan antara mengetuk ikon aplikasi, notifikasi, atau titik entri lainnya, dengan data pengguna yang ditampilkan di layar.
Targetkan beberapa sasaran pengaktifan berikut di aplikasi Anda:
Cold start berlangsung kurang dari 500 md. Cold start terjadi saat aplikasi yang diluncurkan tidak ada di dalam memori sistem. Proses ini terjadi saat aplikasi diluncurkan pertama kali sejak dimulai ulang atau sejak proses aplikasi dihentikan oleh pengguna atau sistem.
Sebaliknya, warm start terjadi saat aplikasi sudah beroperasi di latar belakang. Cold start memerlukan pekerjaan paling banyak dari sistem, karena harus memuat semuanya dari penyimpanan dan menginisialisasi aplikasi. Cobalah untuk membuat cold start berlangsung dalam 500 md atau kurang.
Latensi P95 dan P99 sangat dekat dengan latensi median. Jika aplikasi memerlukan waktu lama untuk dimulai, pengalaman pengguna aplikasi tersebut dinilai buruk. Komunikasi antar-proses (IPC) dan I/O yang tidak perlu selama jalur penting peluncuran aplikasi dapat mengalami pertentangan kunci dan menyebabkan inkonsistensi.
- Jank scroll
Jank adalah istilah yang menjelaskan gangguan visual yang terjadi saat sistem tidak dapat membuat dan menyediakan frame tepat waktu untuk menggambarnya ke layar pada ritme 60 Hz yang diminta atau yang lebih tinggi. Jank terlihat paling jelas saat men-scroll, ketika alur animasi yang lancar mengalami gangguan. Jank muncul saat gerakan terjeda untuk satu atau beberapa frame, karena aplikasi membutuhkan waktu lebih lama untuk merender konten daripada durasi frame pada sistem.
Aplikasi harus menargetkan kecepatan refresh 90 Hz. Kecepatan rendering konvensional adalah 60 Hz, tetapi banyak perangkat baru beroperasi dalam mode 90 Hz selama interaksi pengguna, seperti men-scroll. Beberapa perangkat mendukung kecepatan yang lebih tinggi hingga 120 Hz.
Untuk melihat kecepatan refresh yang digunakan oleh perangkat pada waktu tertentu, aktifkan overlay menggunakan Opsi Developer > Tampilkan kecepatan refresh di bagian Proses debug.
- Transisi yang tidak lancar
Hal ini terlihat selama interaksi, seperti saat beralih antar-tab atau memuat aktivitas baru. Jenis transisi ini harus dalam bentuk animasi yang halus dan tidak menyertakan penundaan atau kedipan visual.
- Inefisiensi daya
Melakukan pekerjaan akan mengurangi daya baterai, dan melakukan pekerjaan yang tidak perlu akan mengurangi daya tahan baterai.
Alokasi memori, yang berasal dari pembuatan objek baru di dalam kode, dapat menjadi penyebab tugas yang signifikan dalam sistem. Hal ini karena alokasi itu sendiri tidak hanya memerlukan upaya dari Android Runtime (ART), tetapi pengosongan objek ini nantinya (pembersihan sampah memori) juga memerlukan waktu dan upaya. Alokasi dan pengumpulan berlangsung jauh lebih cepat dan lebih efisien, terutama untuk objek sementara. Meskipun menghindari pengalokasian objek setiap kali memungkinkan dianggap sebagai praktik terbaik, sebaiknya lakukan hal yang paling sesuai untuk aplikasi dan arsitektur Anda. Menghemat alokasi dengan risiko kode yang tidak dapat dipertahankan bukanlah praktik terbaik, mengingat kemampuan yang dimiliki ART.
Namun, tindakan ini membutuhkan upaya, jadi perlu diingat bahwa tindakan ini dapat menyebabkan masalah performa jika Anda mengalokasikan banyak objek di loop dalam.
Mengidentifikasi masalah
Kami merekomendasikan alur kerja berikut untuk mengidentifikasi dan memperbaiki masalah performa:
- Identifikasi dan periksa perjalanan penting pengguna berikut:
- Alur peluncuran umum, termasuk dari peluncur dan notifikasi.
- Layar tempat pengguna men-scroll data.
- Transisi antar-layar.
- Alur yang berjalan lama, seperti navigasi atau pemutaran musik.
- Periksa semua yang terjadi selama alur sebelumnya dengan menggunakan alat proses debug
berikut:
- Perfetto: memungkinkan Anda melihat apa yang terjadi di seluruh perangkat dengan data pengaturan waktu yang akurat.
- Memory Profiler: memungkinkan Anda melihat alokasi memori yang terjadi pada heap.
- Simpleperf: menampilkan flamegraph panggilan fungsi yang menggunakan sebagian besar CPU selama periode waktu tertentu. Ketika Anda mengidentifikasi sesuatu yang memerlukan waktu lama di Systrace, tetapi Anda tidak tahu alasannya, Simpleperf dapat memberikan informasi tambahan.
Untuk memahami dan men-debug masalah performa ini, sangat penting untuk melakukan debug setiap pengujian yang dijalankan secara manual. Anda tidak dapat mengganti langkah sebelumnya dengan menganalisis data gabungan. Namun, untuk memahami apa yang sebenarnya dilihat pengguna dan mengidentifikasi saat terjadinya regresi, penting untuk menyiapkan pengumpulan metrik di dalam pengujian otomatis dan di kolom:
- Alur pengaktifan
- Metrik kolom: Waktu startup Konsol Play
- Pengujian lab: menguji peluncuran dengan Macrobenchmark
- Jank
- Metrik kolom
- Tanda vital frame Konsol Play: di Konsol Play, Anda tidak dapat mempersempit metrik ke perjalanan pengguna tertentu. Fungsi ini hanya melaporkan keseluruhan jank yang ada di seluruh aplikasi.
- Pengukuran kustom dengan
FrameMetricsAggregator
: Anda dapat menggunakanFrameMetricsAggregator
untuk merekam metrik jank selama alur kerja.
- Pengujian lab
- Men-scroll dengan Macrobenchmark.
- Macrobenchmark mengumpulkan waktu render frame dengan menggunakan perintah
dumpsys gfxinfo
yang mengelompokkan perjalanan pengguna. Cara ini digunakan untuk memahami variasi di dalam jank selama perjalanan pengguna tertentu. MetrikRenderTime
, yang menyoroti lamanya waktu yang diperlukan untuk menggambar frame, lebih penting daripada jumlah frame yang mengalami jank untuk mengidentifikasi regresi atau peningkatan.
- Metrik kolom
Masalah verifikasi Link Aplikasi
Link Aplikasi adalah deep link yang didasarkan pada URL situs Anda yang diverifikasi untuk termasuk dalam situs web Anda. Berikut adalah alasan yang dapat menyebabkan Link Aplikasi verifikasi gagal.
- Cakupan filter intent: hanya tambahkan
autoVerify
ke filter intent untuk URL yang aplikasi Anda merespons. - Pengalihan protokol yang belum diverifikasi: pengalihan sisi server dan subdomain yang belum diverifikasi
dianggap sebagai risiko keamanan
dan kegagalan verifikasi. Mereka menyebabkan
autoVerify
link gagal. Misalnya, mengalihkan tautan dari HTTP ke HTTPS, seperti example.com ke www.example.com, tanpa memverifikasi tautan HTTPS dapat menyebabkan kegagalan verifikasi. Pastikan untuk memverifikasi Link Aplikasi dengan menambahkan intent filter. - Link yang tidak dapat diverifikasi: menambahkan link yang tidak dapat diverifikasi untuk tujuan pengujian dapat menyebabkan sistem tidak memverifikasi Link Aplikasi untuk aplikasi Anda.
- Server yang tidak dapat diandalkan: pastikan server Anda dapat terhubung ke aplikasi klien.
Menyiapkan aplikasi untuk analisis performa
Penting untuk melakukan penyiapan yang benar guna mendapatkan benchmark yang akurat, dapat diulang, dan dapat ditindaklanjuti dari aplikasi. Uji pada sistem yang sedekat mungkin dengan produksi, sambil meredam sumber derau. Bagian ini menampilkan langkah-langkah khusus APK dan sistem yang dapat Anda terapkan untuk mempersiapkan penyiapan pengujian, beberapa di antaranya mencakup kasus penggunaan khusus.
Tracepoint
Aplikasi dapat menginstrumentasikan kodenya dengan peristiwa rekaman aktivitas kustom.
Saat aktivitas direkam, perekaman aktivitas menimbulkan overhead kecil sekitar 5μs per bagian, jadi jangan dilakukan di setiap metode. Perekaman aktivitas pada bagian tugas yang lebih besar dengan >0,1 md dapat memberikan insight yang signifikan tentang bottleneck.
Pertimbangan APK
Varian debug dapat berguna untuk pemecahan
masalah dan melambangkan contoh {i>stack<i},
tetapi berdampak buruk pada performa. Perangkat yang menjalankan Android 10 (API
Level 29) dan yang lebih tinggi dapat menggunakan profileable android:shell="true"
di
untuk mengaktifkan pembuatan profil di build rilis.
Gunakan konfigurasi penyingkatan kode berkelas produksi. Bergantung pada sumber daya yang digunakan aplikasi Anda, hal ini dapat berdampak besar pada performa. Agak besar Konfigurasi ProGuard menghapus tracepoint, jadi pertimbangkan untuk menghapus aturan tersebut untuk konfigurasi tempat Anda menjalankan pengujian.
Kompilasi
Kompilasi aplikasi Anda di perangkat ke status yang diketahui—secara umum speed
atau
speed-profile
. Aktivitas tepat waktu (JIT) latar belakang dapat memiliki
overhead performa, dan Anda akan sering mencapainya jika menginstal ulang APK
di antara pengujian. Berikut adalah perintah untuk melakukannya:
adb shell cmd package compile -m speed -f com.google.packagename
Mode kompilasi speed
mengompilasi aplikasi sepenuhnya. Mode speed-profile
mengompilasi aplikasi sesuai dengan profil jalur kode yang digunakan, yang
dikumpulkan selama penggunaan aplikasi. Terkadang sulit untuk mengumpulkan profil secara konsisten
dan benar, jadi jika Anda memutuskan untuk menggunakannya, pastikan profil
tersebut mengumpulkan sesuatu yang diharapkan. Profil tersebut berada di lokasi berikut:
/data/misc/profiles/ref/[package-name]/primary.prof
Macrobenchmark memungkinkan Anda menentukan mode kompilasi secara langsung.
Pertimbangan sistem
Untuk pengukuran level rendah dan fidelitas tinggi, kalibrasikan perangkat Anda. Jalankan perbandingan A/B di perangkat dan versi OS yang sama. Mungkin akan ditemukan perbedaan yang signifikan dalam hal performa, bahkan pada jenis perangkat yang sama.
Di perangkat yang telah di-root, pertimbangkan untuk menggunakan skrip lockClocks
untuk
Microbenchmark. Di antara hal lain, skrip ini melakukan hal berikut:
- Menempatkan CPU pada frekuensi yang tetap.
- Menonaktifkan core kecil dan mengonfigurasi GPU.
- Menonaktifkan throttling termal.
Sebaiknya jangan gunakan skrip lockClocks
untuk pengujian yang berfokus pada pengalaman pengguna
seperti peluncuran aplikasi, pengujian DoU, dan pengujian jank, tetapi penggunaan skrip mungkin penting untuk
mengurangi derau di dalam pengujian Microbenchmark.
Jika memungkinkan, pertimbangkan untuk menggunakan framework pengujian seperti Macrobenchmark, yang dapat mengurangi derau dalam pengukuran dan mencegah ketidakakuratan pengukuran.
Waktu pengaktifan aplikasi lambat: aktivitas trampolin yang tidak perlu
Aktivitas trampolin dapat memperpanjang waktu peluncuran aplikasi dan
penting untuk diketahui jika aplikasi melakukannya. Seperti yang ditunjukkan di contoh rekaman aktivitas
berikut, satu activityStart
langsung diikuti oleh activityStart
lainnya
tanpa frame yang digambar oleh aktivitas pertama.
Gambar 1. Rekaman aktivitas yang menunjukkan aktivitas trampolin.
Hal ini dapat terjadi di titik entri notifikasi maupun titik entri peluncuran aplikasi reguler, dan biasanya Anda dapat mengatasinya dengan memfaktorkan ulang. Misalnya, jika Anda menggunakan aktivitas tersebut untuk melakukan penyiapan sebelum aktivitas lain berjalan, faktorkan kode ini ke dalam komponen atau library yang dapat digunakan kembali.
Alokasi yang tidak diperlukan memicu seringnya GC
Anda mungkin akan melihat pembersihan sampah memori (GC) terjadi lebih sering daripada yang Anda harapkan terjadi di Systrace.
Di contoh berikut, setiap 10 detik selama operasi yang berjalan lama adalah indikator bahwa aplikasi mungkin dialokasikan secara tidak perlu tetapi konsisten dari waktu ke waktu:
Gambar 2. Rekaman aktivitas yang menunjukkan spasi antar-peristiwa GC.
Anda mungkin juga menyadari bahwa stack panggilan tertentu membutuhkan sebagian besar alokasi saat menggunakan Memory Profiler. Anda tidak perlu menghilangkan semua alokasi secara agresif, karena hal ini dapat membuat kode lebih sulit dipertahankan. Sebagai gantinya, mulailah dengan mengerjakan hotspot alokasi.
Frame yang mengalami jank
Pipeline grafis relatif rumit, dan mungkin terdapat perbedaan kecil mengenai ketentuan apakah pengguna pada akhirnya akan melihat penurunan frame atau tidak. Di beberapa kasus, platform dapat "menyelamatkan" frame dengan menggunakan buffering. Namun, Anda dapat mengabaikan sebagian besar perbedaan kecil tersebut untuk mengidentifikasi frame yang bermasalah dari perspektif aplikasi Anda.
Jika frame digambar dengan sedikit pekerjaan yang diperlukan dari aplikasi,
tracepoint Choreographer.doFrame()
terjadi pada ritme 16,7 md di perangkat
60 FPS:
Gambar 3. Rekaman aktivitas menunjukkan frame cepat yang sering.
Saat memperkecil dan menavigasi rekaman aktivitas, terkadang Anda akan melihat frame memerlukan waktu sedikit lebih lama untuk diselesaikan, tetapi itu tidak masalah karena frame tersebut tidak memerlukan waktu lebih dari 16,7 md:
Gambar 4. Rekaman aktivitas yang menunjukkan frame cepat yang sering dengan burst tugas berkala.
Jika Anda melihat gangguan pada ritme reguler ini, gangguan itu disebut frame yang mengalami jank, seperti yang ditunjukkan pada gambar 5:
Gambar 5. Rekaman aktivitas yang menunjukkan frame yang mengalami jank.
Anda dapat berlatih dalam mengidentifikasinya.
Gambar 6. Rekaman aktivitas yang menunjukkan lebih banyak frame yang mengalami jank.
Di beberapa kasus, Anda perlu memperbesar tracepoint untuk mengetahui informasi selengkapnya tentang
tampilan mana yang di-inflate atau apa yang dilakukan RecyclerView
. Di kasus
lain, Anda mungkin harus melakukan pemeriksaan lebih lanjut.
Untuk informasi selengkapnya tentang cara mengidentifikasi frame yang mengalami jank dan mendebug penyebabnya, lihat Rendering lambat.
Kesalahan umum RecyclerView
Membatalkan validasi seluruh data pendukung RecyclerView
secara tidak perlu dapat
menyebabkan waktu rendering frame yang lama dan jank. Sebaliknya, untuk
meminimalkan jumlah
tampilan yang perlu diperbarui, hanya
membatalkan validasi data yang berubah.
Lihat Menyajikan data dinamis untuk mengetahui cara menghindari notifyDatasetChanged()
yang mahal
yang menyebabkan konten diperbarui, bukan menggantikannya sepenuhnya.
Jika Anda tidak mendukung setiap RecyclerView
bertingkat dengan benar, hal ini dapat menyebabkan
RecyclerView
internal sepenuhnya dibuat ulang setiap saat. Setiap susunan bertingkat,
RecyclerView
bagian dalam harus memiliki RecycledViewPool
yang ditetapkan untuk membantu memastikan
tampilan dapat didaur ulang di antara setiap RecyclerView
bagian dalam.
Tidak melakukan pengambilan data yang cukup, atau tidak mengambil data secara tepat waktu, dapat membuat aktivitas membuka bagian bawah daftar scroll menjadi terganggu saat pengguna harus menunggu lebih banyak data dari server. Meskipun secara teknis gangguan ini bukan jank, karena tidak ada batas waktu frame yang terlewat, Anda dapat meningkatkan UX secara signifikan dengan mengubah waktu dan kuantitas pengambilan data agar pengguna tidak perlu menunggu data.
Mendebug aplikasi Anda
Berikut ini adalah berbagai metode untuk men-debug performa aplikasi. Lihat video berikut ini untuk ikhtisar pelacakan sistem dan penggunaan Android Profiler Android Studio.
Men-debug startup aplikasi dengan Systrace
Lihat Waktu startup aplikasi untuk ringkasan proses startup aplikasi, dan lihat video berikut untuk ikhtisar pelacakan sistem.
Anda dapat membedakan jenis startup dalam tahap berikut:
- Cold startup: memulai pembuatan proses baru tanpa status tersimpan.
- Warm startup: membuat ulang aktivitas sambil menggunakan kembali proses, atau membuat ulang proses dengan status tersimpan.
- Hot startup: memulai ulang aktivitas dan memulai saat inflation.
Sebaiknya rekam Systrace menggunakan aplikasi Pelacakan Sistem di perangkat. Untuk Android 10 dan yang lebih tinggi, gunakan Perfetto. Untuk Android 9 dan yang lebih rendah, gunakan Systrace. Sebaiknya lihat juga file rekaman aktivitas dengan antarmuka berbasis web Penampil rekaman aktivitas Perfetto. Untuk informasi selengkapnya, lihat Ringkasan sistem pelacakan.
Beberapa hal yang harus diperhatikan meliputi:
- Pantau pertentangan: persaingan untuk sumber daya yang dilindungi monitor dapat menimbulkan keterlambatan yang signifikan dalam startup aplikasi.
Transaksi binder sinkron: cari transaksi yang tidak perlu di jalur kritis aplikasi Anda. Jika transaksi yang diperlukan mahal, pertimbangkan untuk bekerja dengan tim platform terkait untuk melakukan perbaikan.
GC serentak: hal ini umum dan berdampak relatif rendah, tetapi jika Anda sering mengalaminya, pertimbangkan untuk memeriksanya dengan memori Android Studio profiler.
I/O: memeriksa I/O yang dilakukan selama startup, dan mencari jeda yang panjang.
Aktivitas yang signifikan pada thread lain: ini dapat mengganggu UI thread, jadi perhatikan pekerjaan latar belakang selama {i>startup<i}.
Sebaiknya panggil reportFullyDrawn
saat proses startup selesai dari
perspektif aplikasi untuk meningkatkan pelaporan metrik startup aplikasi. Lihat Waktu
ke tampilan penuh untuk mengetahui informasi selengkapnya tentang cara menggunakan reportFullyDrawn
.
Anda bisa mengekstrak waktu mulai yang ditentukan RFD melalui pemroses rekaman aktivitas Perfetto,
dan peristiwa trace yang terlihat oleh pengguna dimunculkan.
Menggunakan Pelacakan Sistem pada perangkat
Anda dapat menggunakan aplikasi tingkat sistem yang disebut Pelacakan Sistem untuk merekam sistem
rekaman aktivitas di perangkat. Aplikasi ini memungkinkan Anda merekam aktivitas dari perangkat tanpa
mencolokkan atau menghubungkannya ke adb
.
Menggunakan Memory Profiler Android Studio
Anda dapat menggunakan Memory Profiler Android Studio untuk memeriksa tekanan memori yang mungkin disebabkan oleh kebocoran memori atau pola penggunaan yang buruk. Alat ini menyediakan tentang alokasi objek.
Anda dapat memperbaiki masalah memori di aplikasi dengan mengikuti informasi dari Memory Profiler untuk melacak alasan dan seberapa sering GC terjadi.
Untuk membuat profil memori aplikasi, lakukan langkah-langkah berikut:
Mendeteksi masalah memori.
Rekam sesi pembuatan profil memori dari perjalanan pengguna yang ingin Anda fokuskan. Cari jumlah objek yang meningkat, seperti ditunjukkan pada gambar 7, yang akhirnya mengarah ke GC, seperti yang ditunjukkan pada gambar 8.
Gambar 7. Menambah jumlah objek.
Gambar 8. Pembersihan sampah memori.
Setelah mengidentifikasi perjalanan pengguna yang menambah tekanan memori, analisis untuk akar penyebab tekanan memori.
Mendiagnosis hot spot tekanan memori.
Pilih rentang di linimasa untuk memvisualisasikan Alokasi dan Shallow Size, seperti yang ditunjukkan pada gambar 9.
Gambar 9. Nilai untuk Allocations dan Shallow Ukuran.
Ada beberapa cara untuk mengurutkan data ini. Berikut ini adalah beberapa contoh bagaimana setiap tampilan dapat membantu Anda menganalisis masalah.
Sort by class: berguna jika Anda ingin menemukan class yang menghasilkan objek yang biasanya di-cache atau digunakan kembali dari kumpulan memori.
Misalnya, jika Anda melihat aplikasi yang membuat 2.000 objek class yang disebut "Vertex" setiap detik, jumlah Alokasi meningkat sebesar 2.000 setiap detik dan Anda melihatnya ketika mengurutkan berdasarkan kelas. Jika Anda ingin menggunakan kembali objek ini untuk menghindari menghasilkan sampah, mengimplementasikan kumpulan memori.
Sort by callstack: berguna ketika Anda ingin mencari tahu sumber data jalur tempat memori dialokasikan, seperti di dalam loop atau di dalam fungsi spesifik yang melakukan banyak pekerjaan alokasi.
Shallow Size: hanya melacak memori objek itu sendiri. Berguna untuk melacak kelas sederhana yang sebagian besar terdiri dari nilai primitif saja.
Retained Size: menunjukkan total memori karena objek dan referensi yang hanya direferensikan oleh objek. Hal ini berguna untuk melacak memori tekanan karena objek yang kompleks. Untuk mendapatkan nilai ini, gunakan memori penuh seperti yang ditunjukkan pada gambar 10, dan Retained Size ditambahkan sebagai kolom, sebagai yang ditunjukkan pada gambar 11.
Gambar 10. Dump memori penuh.
Gambar 11. Kolom Retained Size.
Mengukur dampak pengoptimalan.
GC lebih terlihat dan lebih mudah mengukur dampak memori pengoptimalan. Saat pengoptimalan mengurangi tekanan memori, Anda melihat lebih sedikit GC.
Untuk mengukur dampak pengoptimalan, di linimasa profiler, ukur waktu antar GC. Anda kemudian dapat melihatnya memerlukan waktu lebih lama di antara GC.
Dampak utama peningkatan memori adalah sebagai berikut:
- Penonaktifan memori habis kemungkinan akan berkurang jika aplikasi tidak terus-menerus mencapai tekanan memori.
- Memiliki lebih sedikit GC meningkatkan metrik jank, terutama di P99. Hal ini karena GC menyebabkan pertentangan CPU, yang dapat menyebabkan perenderan tugas yang ditangguhkan saat GC terjadi.
Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Analisis dan pengoptimalan startup aplikasi {:#app-startup-analysis-optimization}
- Periode frozen
- Menulis Macrobenchmark