Cara mengelola hierarki objek
View
dapat memengaruhi
performa aplikasi Anda secara signifikan. Halaman ini menjelaskan cara menilai apakah hierarki tampilan memperlambat
aplikasi Anda atau tidak, dan menawarkan beberapa strategi untuk mengatasi masalah yang mungkin terjadi.
Halaman ini berfokus pada peningkatan tata letak berbasis View
. Untuk mengetahui informasi tentang cara meningkatkan
performa Jetpack Compose, lihat performa
Jetpack Compose.
Performa tata letak dan pengukuran
Pipeline rendering meliputi tahap tata letak dan pengukuran, di mana sistem
secara tepat memosisikan item yang relevan dalam hierarki tampilan Anda. Bagian pengukuran pada tahap
ini menentukan ukuran dan batas objek View
. Bagian tata letak
menentukan posisi objek View
di layar.
Kedua tahap pipeline ini menimbulkan sedikit biaya per tampilan atau tata letak yang diproses. Biasanya,
biaya ini tidak besar dan tidak terlalu memengaruhi performa. Namun, lebih baik lagi
jika aplikasi menambahkan atau menghapus objek View
, seperti saat objek
RecyclerView
mendaur ulang atau menggunakannya kembali. Biayanya juga dapat lebih tinggi jika objek View
perlu
mempertimbangkan pengubahan ukuran agar dapat memenuhi batasannya. Misalnya, jika aplikasi Anda memanggil
SetText()
pada objek View
yang menggabungkan teks, View
mungkin perlu diubah ukurannya.
Jika memakan waktu terlalu lama, proses ini dapat mencegah frame melakukan rendering dalam 16 milidetik yang diizinkan, yang dapat membuat frame turun dan membuat animasi menjadi tersendat.
Karena Anda tidak dapat memindahkan operasi ini ke thread pekerja, aplikasi Anda harus memprosesnya di thread utama. Sebaiknya optimalkan operasi tersebut agar menghemat waktu.
Mengelola tata letak yang kompleks
Tata Letak Android memungkinkan Anda menyusun bertingkat objek UI dalam hierarki tampilan. Penyusunan bertingkat (nesting) ini juga dapat menimbulkan biaya tata letak. Saat aplikasi Anda memproses objek untuk tata letak, aplikasi juga melakukan proses yang sama pada semua turunan tata letak.
Untuk tata letak yang rumit, terkadang biaya hanya timbul saat sistem menghitung tata letak untuk
pertama kali. Misalnya, saat aplikasi Anda mendaur ulang item daftar yang kompleks dalam objek RecyclerView
,
sistem tersebut perlu membuat tata letak semua objek tersebut. Dalam contoh lain, perubahan trivial dapat
menyebarkan rantai ke arah induk sampai mencapai objek yang tidak memengaruhi ukuran
induk.
Alasan umum tata letak memerlukan waktu yang lama adalah saat hierarki objek View
disusun bertingkat dengan satu sama lain. Setiap objek tata letak bertingkat menambahkan biaya ke tahapan tata letak. Makin datar
hierarki Anda, makin sedikit waktu yang dibutuhkan untuk menyelesaikan tahapan tata letak.
Sebaiknya gunakan
Layout Editor untuk membuat
ConstraintLayout
, bukan
RelativeLayout
atau
LinearLayout
, karena
umumnya lebih efisien dan mengurangi penyusunan bertingkat tata letak. Namun, untuk tata letak sederhana yang
dapat dicapai menggunakan
FrameLayout
, sebaiknya
gunakan FrameLayout
.
Jika Anda menggunakan class RelativeLayout
, Anda mungkin dapat mencapai efek yang sama,
dengan biaya yang lebih rendah, menggunakan tampilan LinearLayout
yang bertingkat dan tidak tertimbang. Namun,
jika Anda menggunakan tampilan LinearLayout
bertingkat dan berbobot, biaya tata letak jauh lebih tinggi
karena memerlukan beberapa penerusan tata letak, seperti yang dijelaskan di bagian berikutnya.
Sebaiknya, gunakan juga RecyclerView
, bukan
ListView
, karena dapat mendaur ulang
tata letak item daftar individu, yang keduanya lebih efisien dan dapat meningkatkan performa
scroll.
Taksasi ganda
Biasanya, framework akan menjalankan tahap tata letak atau pengukuran dalam satu penerusan. Namun, dalam beberapa kasus tata letak yang rumit, framework mungkin harus melakukan iterasi beberapa kali pada bagian hierarki yang memerlukan beberapa penerusan untuk di-resolve sebelum akhirnya menempatkan elemen. Keharusan untuk melakukan lebih dari satu iterasi tata letak dan pengukuran disebut sebagai taksasi ganda.
Misalnya, saat Anda menggunakan penampung RelativeLayout
, yang memungkinkan Anda memosisikan
objek View
sehubungan dengan posisi objek View
yang lain, framework
akan menjalankan urutan berikut:
- Mengeksekusi penerusan tata letak dan pengukuran, di mana framework akan menghitung setiap posisi dan ukuran objek turunan sesuai dengan permintaan setiap turunan.
- Menggunakan data ini, yang juga mempertimbangkan bobot objek, untuk mengetahui posisi yang tepat dari tampilan terkait.
- Melakukan penerusan tata letak kedua untuk menyelesaikan posisi objek.
- Berpindah ke tahap selanjutnya dari proses rendering.
Makin banyak level yang dimiliki hierarki tampilan Anda, makin besar kemungkinan penalti performanya.
Seperti yang disebutkan sebelumnya, ConstraintLayout
umumnya lebih efisien daripada
tata letak lain, kecuali FrameLayout
. Fungsi ini tidak terlalu rentan terhadap beberapa penerusan tata letak, dan dalam banyak
kasus, menghilangkan kebutuhan untuk menyusun bertingkat tata letak.
Penampung selain RelativeLayout
juga dapat meningkatkan taksasi ganda. Contoh:
- Tampilan
LinearLayout
dapat menghasilkan penerusan tata letak dan pengukuran ganda jika dibuat horizontal. Penerusan tata letak dan pengukuran ganda juga dapat terjadi pada orientasi vertikal jika Anda menambahkanmeasureWithLargestChild
, yang dalam hal ini framework mungkin perlu melakukan penerusan kedua untuk me-resolve ukuran objek yang tepat. GridLayout
juga memungkinkan pemosisian relatif, tetapi biasanya menghindari taksasi ganda dengan memproses terlebih dahulu hubungan posisi di antara tampilan turunan. Namun, jika tata letak menggunakan bobot atau mengisinya dengan classGravity
, manfaat pemrosesan tersebut akan hilang, sehingga framework mungkin harus melakukan beberapa penerusan jika penampungnya adalahRelativeLayout
.
Beberapa penerusan tata letak dan pengukuran tidak selalu membebani performa. Namun, penerusan tersebut dapat menjadi beban jika berada di tempat yang salah. Berhati-hatilah jika salah satu kondisi berikut berlaku pada penampung Anda:
- Merupakan elemen root dalam hierarki tampilan Anda.
- Memiliki hierarki tampilan yang mendalam di bawahnya.
- Ada banyak instance yang mengisi layar, mirip dengan turunan dalam objek
ListView
.
Mendiagnosis masalah hierarki tampilan
Performa tata letak merupakan masalah yang kompleks dengan banyak faset. Alat berikut dapat membantu Anda mengidentifikasi lokasi terjadinya bottleneck performa. Beberapa alat memberikan informasi yang kurang pasti, tetapi dapat memberikan petunjuk yang bermanfaat.
Perfetto
Perfetto adalah alat yang menyediakan data tentang performa. Anda dapat membuka rekaman aktivitas Android di UI Perfetto.
Rendering GPU profil
Alat rendering GPU Profil di perangkat, yang tersedia di perangkat yang didukung oleh Android 6.0 (level API 23) dan yang lebih baru, dapat memberi informasi konkret tentang bottleneck performa. Alat ini memungkinkan Anda melihat berapa lama waktu yang dibutuhkan oleh tahap tata letak dan pengukuran untuk setiap frame rendering. Data ini dapat membantu Anda mendiagnosis masalah performa runtime dan membantu Anda menentukan apakah ada masalah tata letak dan pengukuran yang perlu Anda atasi.
Dalam representasi grafis data yang ditangkapnya, rendering GPU Profil menggunakan warna biru untuk menggambarkan waktu pembuatan tata letak. Untuk informasi selengkapnya tentang cara menggunakan alat ini, lihat kecepatan rendering GPU Profil.
Lint
Alat Lint Android Studio dapat membantu Anda mendeteksi inefisiensi dalam hierarki tampilan. Untuk menggunakan alat ini, pilih Analyze > Inspect Code, seperti yang ditunjukkan pada gambar 1.
Informasi tentang berbagai item tata letak muncul di Android > Lint > Performance. Untuk melihat detail selengkapnya, klik setiap item untuk meluaskannya dan menampilkan informasi selengkapnya di panel yang berada di sisi kanan layar. Gambar 2 menunjukkan contoh informasi yang diperluas.
Mengklik item akan memunculkan masalah yang terkait dengan item tersebut di panel sebelah kanan.
Untuk memahami topik dan masalah spesifik di bidang ini lebih lanjut, lihat dokumentasi Lint.
Layout Inspector
Alat Layout Inspector Android Studio memberikan representasi visual dari hierarki tampilan aplikasi Anda. Ini adalah cara yang baik untuk menavigasi hierarki aplikasi Anda, dengan representasi visual yang jelas dari rantai induk tampilan tertentu. Selain itu, alat ini memungkinkan Anda memeriksa tata letak yang dibuat oleh aplikasi Anda.
Tampilan yang disajikan oleh Layout Inspector juga dapat membantu mengidentifikasi masalah performa yang timbul dari taksasi ganda. Ini juga dapat memberi Anda cara untuk mengidentifikasi rantai tata letak bertingkat yang mendalam, atau area tata letak dengan jumlah turunan bertingkat yang banyak, yang dapat menjadi sumber biaya performa. Dalam hal ini, tahap tata letak dan pengukuran dapat membutuhkan biaya yang mahal dan mengakibatkan masalah performa.
Untuk mengetahui informasi selengkapnya, lihat Men-debug tata letak dengan Layout Inspector dan Layout Validation.
Menyelesaikan masalah hierarki tampilan
Konsep dasar di balik penyelesaian masalah performa yang muncul dari hierarki tampilan bisa menjadi sulit dalam praktiknya. Mencegah hierarki tampilan menerapkan penalti performa terdiri dari proses meratakan hierarki tampilan dan mengurangi taksasi ganda. Bagian ini membahas beberapa strategi untuk mencapai tujuan ini.
Menghapus tata letak bersarang yang redundan
ConstraintLayout
adalah library Jetpack dengan beragam mekanisme dalam jumlah besar untuk memosisikan tampilan dalam
tata letak. Tindakan ini akan mengurangi kebutuhan untuk menyusun bertingkat satu ConstaintLayout
dan dapat membantu meratakan hierarki
tampilan. Biasanya lebih mudah untuk meratakan hierarki menggunakan ConstraintLayout
dibandingkan
dengan jenis tata letak lainnya.
Developer sering kali menggunakan tata letak bertingkat lebih dari yang diperlukan. Misalnya, penampung
RelativeLayout
mungkin berisi satu turunan yang juga berupa
penampung RelativeLayout
. Susunan bertingkat menyebabkan redundansi dan menambah biaya yang tidak perlu ke
hierarki tampilan. Lint dapat menandai masalah ini untuk Anda, sehingga akan mengurangi waktu debugging.
Mengadopsi merge atau include
Penyebab seringnya terjadi tata letak bertingkat yang redundan adalah
tag
<include>
. Misalnya, Anda dapat menentukan tata letak yang bisa digunakan lagi seperti berikut:
<LinearLayout> <!-- some stuff here --> </LinearLayout>
Selanjutnya, Anda dapat menambahkan tag <include>
untuk menambahkan item berikut ke penampung
induk:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/app_bg" android:gravity="center_horizontal"> <include layout="@layout/titlebar"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/hello" android:padding="10dp" /> ... </LinearLayout>
Include sebelumnya ini sebenarnya tidak perlu menyusun bertingkat tata letak pertama dalam tata letak kedua.
Tag
<merge>
dapat membantu mencegah masalah ini. Untuk mengetahui informasi tentang tag ini, lihat Menggunakan tag <merge>.
Mengadopsi tata letak yang lebih murah
Anda mungkin tidak dapat menyesuaikan skema tata letak yang ada agar tidak berisi tata letak redundan. Dalam kasus tertentu, satu-satunya solusi yang mungkin adalah meratakan hierarki Anda dengan beralih ke jenis tata letak yang sama sekali berbeda.
Misalnya, Anda mungkin menemukan bahwa
TableLayout
menyediakan fungsi yang sama
dengan tata letak yang lebih kompleks dengan banyak dependensi posisi. Library Jetpack
ConstraintLayout
menyediakan fungsi yang mirip dengan RelativeLayout
, ditambah fitur lainnya untuk membantu membuat
tata letak yang lebih datar dan efisien.