Waktu startup aplikasi

Tetap teratur dengan koleksi Simpan dan kategorikan konten berdasarkan preferensi Anda.

Pengguna mengharapkan aplikasi responsif dan cepat untuk dimuat. Aplikasi dengan waktu mulai lambat tidak akan memenuhi harapan tersebut, dan dapat mengecewakan pengguna. Pengalaman buruk semacam ini dapat menyebabkan pengguna memberikan rating yang buruk terhadap aplikasi Anda di Play Store, atau bahkan berhenti menggunakan aplikasi Anda.

Dokumen ini memberikan informasi yang akan membantu Anda mengoptimalkan waktu peluncuran aplikasi Anda. Diawali dengan menjelaskan internal dari proses peluncuran. Selanjutnya, membahas cara menggambarkan performa startup. Terakhir, menjelaskan beberapa masalah waktu mulai umum dan memberikan beberapa petunjuk tentang cara mengatasinya.

Memahami berbagai status startup aplikasi

Peluncuran aplikasi dapat dilakukan dalam salah satu dari tiga status berikut, masing-masing memengaruhi waktu yang diperlukan aplikasi Anda agar terlihat oleh pengguna: cold start, warm start, atau hot start. Dalam cold start, aplikasi akan dimulai dari awal. Dalam status yang lain, sistem diharuskan untuk memindah aplikasi yang berjalan dari latar belakang ke latar depan. Sebaiknya selalu lakukan pengoptimalan berdasarkan asumsi cold start. Melakukan hal tersebut juga dapat meningkatkan performa warm start dan hot start.

Untuk mengoptimalkan aplikasi Anda agar startup-nya cepat, sangatlah berguna jika Anda memahami apa yang terjadi pada tingkat sistem dan aplikasi, serta bagaimana interaksinya dalam setiap status.

Cold start

Cold start mengacu pada aplikasi yang dimulai dari awal: sampai tahap start ini, proses sistem belum membuat proses aplikasi. Cold start terjadi jika aplikasi Anda diluncurkan untuk pertama kalinya sejak perangkat di-booting, atau sejak sistem menutup aplikasi. Jenis start ini menghadirkan tantangan terbesar dalam hal meminimalkan waktu startup, karena sistem dan aplikasi memiliki pekerjaan yang lebih banyak daripada status peluncuran lainnya.

Di awal cold start, sistem memiliki tiga tugas. Tugas tersebut adalah:

  1. Memuat dan meluncurkan aplikasi.
  2. Menampilkan jendela awal kosong untuk aplikasi segera setelah peluncuran.
  3. Membuat proses aplikasi.

Segera setelah sistem membuat proses aplikasi, proses aplikasi bertanggung jawab untuk tahap selanjutnya:

  1. Membuat objek aplikasi.
  2. Meluncurkan thread utama.
  3. Membuat aktivitas utama.
  4. Meluaskan tampilan.
  5. Menata layar.
  6. Menjalankan penggambaran awal.

Setelah proses aplikasi menyelesaikan penggambaran awal, proses sistem menukar jendela latar belakang yang saat ini ditampilkan, menggantinya dengan aktivitas utama. Pada tahap ini, pengguna dapat mulai menggunakan aplikasi.

Gambar 1 menunjukkan bagaimana sistem dan proses aplikasi saling berbagi tugas satu sama lain.

Gambar 1: Representasi visual bagian-bagian penting dari peluncuran aplikasi cold.

Masalah performa dapat muncul selama pembuatan aplikasi dan pembuatan aktivitas.

Pembuatan aplikasi

Saat aplikasi diluncurkan, jendela awal kosong tetap muncul di layar sampai sistem selesai menggambar aplikasi untuk pertama kalinya. Pada tahap tersebut, proses sistem menukar jendela awal aplikasi Anda, memungkinkan pengguna mulai berinteraksi dengan aplikasi.

Jika Application.onCreate() di aplikasi Anda kelebihan muatan, sistem akan memanggil metode onCreate() pada objek aplikasi Anda. Setelah itu, aplikasi akan memunculkan thread utama, yang juga dikenal sebagai UI thread, dan menugaskannya untuk membuat aktivitas utama Anda.

Pada tahap ini, proses tingkat aplikasi dan sistem akan memproses sesuai dengan tahap siklus proses aplikasi.

Pembuatan aktivitas

Setelah proses aplikasi membuat aktivitas, aktivitas menjalankan operasi berikut:

  1. Menginisialisasi nilai.
  2. Memanggil konstruktor.
  3. Memanggil metode callback, seperti Activity.onCreate(), sesuai dengan status siklus proses aktivitas saat ini.

Biasanya, metode onCreate() memiliki dampak terbesar pada waktu pemuatan karena metode tersebut menjalankan pekerjaan dengan overhead tertinggi: memuat dan meng-inflate tampilan, serta menginisialisasi objek yang perlu dijalankan oleh aktivitas.

Warm start

Warm start mencakup beberapa subset operasi yang berlangsung selama cold start, dan pada saat yang sama menunjukkan overhead yang lebih banyak dari hot start. Ada banyak kemungkinan status yang dapat dianggap sebagai warm start. Sebagai contoh:

  • Pengguna keluar dari aplikasi Anda, tetapi kemudian meluncurkannya kembali. Proses mungkin akan terus berjalan, tetapi aplikasi harus membuat ulang aktivitas dari awal melalui panggilan ke onCreate().

  • Sistem mengeluarkan aplikasi Anda dari memori, lalu pengguna meluncurkannya kembali. Proses dan aktivitas perlu dimulai ulang, tetapi tugas dapat memanfaatkan paket status instance tersimpan yang diteruskan ke onCreate().

Hot start

Hot start pada aplikasi jauh lebih sederhana dan memiliki overhead yang lebih rendah dari cold start. Pada hot start, yang dilakukan semua sistem adalah memindah aktivitas ke latar depan. Jika semua aktivitas aplikasi Anda masih tersimpan di di memori, aplikasi tersebut dapat mengabaikan pengulangan inisialisasi objek, inflate tata letak, dan rendering.

Namun, jika beberapa memori telah dihapus akibat peristiwa pemangkasan memori, seperti onTrimMemory(), objek tersebut perlu dibuat ulang sebagai respons untuk peristiwa hot start.

Hot start menampilkan perilaku di layar yang sama dengan skenario cold start:

Proses sistem menampilkan layar kosong hingga aplikasi selesai merender aktivitas.

Gambar 2: Diagram ini menampilkan berbagai status startup dan setiap prosesnya, dengan setiap status dimulai dari frame pertama yang digambar.

Menggunakan metrik untuk mendeteksi dan mendiagnosis masalah

Untuk mendiagnosis performa waktu mulai dengan benar, Anda dapat melacak metrik yang menampilkan berapa lama aplikasi Anda dimulai. Android menyediakan beberapa cara untuk memberi tahu Anda bahwa aplikasi Anda bermasalah, serta membantu Anda mendiagnosisnya. Android vitals dapat memberi tahu Anda bahwa masalah terjadi, dan alat diagnosis dapat membantu Anda mendiagnosis masalah tersebut.

Manfaat menggunakan metrik startup

Android menggunakan metrik Waktu hingga tampilan awal dan Waktu hingga tampilan penuh untuk mengoptimalkan startup aplikasi cold dan warm. Android Runtime (ART) menggunakan data dari metrik ini untuk mengompilasi kode secara efisien guna mengoptimalkan startup mendatang.

Startup yang lebih cepat menghasilkan interaksi pengguna yang lebih berkelanjutan dengan aplikasi Anda, yang mengurangi instance keluar awal, memulai ulang instance, atau berpindah ke aplikasi lain.

Android vitals

Android vitals dapat membantu meningkatkan performa aplikasi dengan memberi tahu Anda, melalui Konsol Play, jika waktu startup aplikasi Anda berlebihan. Android vitals menganggap waktu startup aplikasi Anda berlebihan jika:

  • Cold startup membutuhkan waktu 5 detik atau lebih lama.
  • Warm startup membutuhkan waktu 2 detik atau lebih lama.
  • Hot startup membutuhkan waktu 1,5 detik atau lebih lama.

Android vitals menggunakan metrik Waktu hingga tampilan awal dan tidak melaporkan data untuk hot startup. Untuk informasi tentang cara Google Play mengumpulkan data Android vitals, lihat dokumentasi Konsol Play.

Waktu hingga tampilan awal

Metrik waktu hingga tampilan awal (TTID) mengukur waktu yang diperlukan aplikasi untuk menghasilkan frame pertamanya, termasuk inisialisasi proses (jika cold start), pembuatan aktivitas (jika cold/warm), dan menampilkan frame pertama.

Cara mengambil TTID

Di Android 4.4 (API level 19) dan yang lebih tinggi, logcat menyertakan baris output yang berisi nilai bernama Displayed. Nilai ini mewakili jumlah waktu yang berlalu antara meluncurkan proses dan menyelesaikan menggambar aktivitas terkait di layar. Waktu yang berlalu mencakup urutan peristiwa berikut:

  • Meluncurkan proses.
  • Menginisialisasi objek.
  • Membuat dan menginisialisasi aktivitas.
  • Meluaskan tata letak.
  • Menggambar aplikasi untuk pertama kalinya.

Baris log yang dilaporkan terlihat mirip dengan contoh berikut:

ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms

Jika Anda melacak output logcat dari command line, atau dalam terminal, Anda dapat menemukan waktu berlalu dengan mudah. Untuk menemukan waktu berlalu di Android Studio, Anda harus menonaktifkan filter dalam tampilan logcat Anda. Filter perlu dinonaktifkan karena server sistem, bukan aplikasi itu sendiri, yang menyalurkan log ini.

Setelah selesai membuat setelan yang benar, Anda dapat dengan mudah menelusuri istilah yang tepat untuk melihat waktunya. Gambar 2 menunjukkan cara menonaktifkan filter, dan, di baris kedua output dari bawah, adalah contoh output logcat dari waktu Displayed.

Gambar 2: Menonaktifkan filter, dan menemukan nilai `Displayed` di logcat.

Metrik Displayed dalam output logcat tidak selalu merekam jumlah waktu sampai semua resource dimuat dan ditampilkan: metrik ini melewatkan resource yang tidak direferensikan di file tata letak atau file yang dibuat aplikasi sebagai bagian dari inisialisasi objek. Metrik tersebut tidak menyertakan resource ini karena memuatnya merupakan suatu proses inline, dan tidak memblokir tampilan awal aplikasi.

Terkadang baris Displayed dalam output logcat berisi kolom tambahan untuk waktu total. Contoh:

ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms (total +1m22s643ms)

Dalam hal ini, pengukuran pertama kali hanya dilakukan untuk aktivitas yang pertama kali digambar. Pengukuran waktu total dimulai saat proses aplikasi dijalankan, dan dapat menyertakan aktivitas lain yang dimulai terlebih dahulu, tetapi tidak menampilkan apa pun di layar. Pengukuran waktu total hanya ditampilkan ketika ada perbedaan antara aktivitas tunggal dan waktu startup total.

Anda juga dapat mengukur waktu hingga tampilan awal dengan menjalankan aplikasi menggunakan perintah ADB Shell Activity Manager. Berikut contohnya:

adb [-d|-e|-s <serialNumber>] shell am start -S -W
com.example.app/.MainActivity
-c android.intent.category.LAUNCHER
-a android.intent.action.MAIN

Metrik Displayed muncul dalam output logcat seperti sebelumnya. Jendela terminal Anda seharusnya juga menampilkan baris berikut:

Starting: Intent
Activity: com.example.app/.MainActivity
ThisTime: 2044
TotalTime: 2044
WaitTime: 2054
Complete

Argumen -c dan -a bersifat opsional dan memungkinkan Anda menentukan <category> dan <action>

Waktu hingga tampilan penuh

Metrik Waktu hingga tampilan penuh (TTFD) mengukur waktu yang dibutuhkan oleh aplikasi untuk menghasilkan frame pertamanya dengan konten lengkap, termasuk konten yang dimuat secara asinkron setelah frame pertama. Umumnya, ini adalah konten daftar utama yang dimuat dari jaringan, seperti yang dilaporkan oleh aplikasi.

Cara mengambil TTFD

Anda dapat menggunakan metode reportFullyDrawn() untuk mengukur waktu yang telah berlalu antara peluncuran aplikasi serta tampilan lengkap semua resource dan hierarki tampilan. Hal ini dapat sangat berguna jika suatu aplikasi menjalankan pemuatan lambat. Dalam pemuatan lambat, aplikasi tidak memblokir penggambaran awal jendela, tetapi memuat resource dan mengupdate hierarki tampilannya secara asinkron.

Jika, akibat pemuatan lambat, tampilan awal aplikasi tidak menyertakan semua resource, sebaiknya pertimbangkan untuk memuat sepenuhnya serta menampilkan semua resource dan tampilan sebagai metrik terpisah: Misalnya, UI mungkin dimuat sepenuhnya, dengan menggambar beberapa teks, tetapi masih belum menampilkan gambar yang harus diambil aplikasi dari jaringan.

Untuk mengatasi masalah ini, Anda dapat memanggil reportFullyDrawn() secara manual untuk memberi tahu sistem bahwa aktivitas Anda sudah menyelesaikan pemuatan lambat. Saat Anda menggunakan metode ini, nilai yang ditampilkan logcat adalah waktu yang telah berlalu dari pembuatan objek aplikasi sampai saat reportFullyDrawn() dipanggil. Berikut adalah contoh dari output logcat:

system_process I/ActivityManager: Fully drawn {package}/.MainActivity: +1s54ms

Output logcat terkadang menyertakan waktu total, seperti yang dibahas dalam Waktu hingga tampilan awal.

Jika mengetahui bahwa waktu tampilan lebih lambat dari yang diinginkan, Anda dapat mencoba mengidentifikasi bottleneck dalam proses startup.

Mengidentifikasi bottleneck

Cara mudah untuk mencari bottleneck adalah dengan CPU Profiler Android Studio. Untuk informasinya, lihat Memeriksa aktivitas CPU dengan CPU Profiler.

Anda juga dapat memperoleh insight tentang potensi bottleneck melalui pelacakan inline di dalam metode onCreate() aplikasi dan aktivitas Anda. Untuk mempelajari pelacakan inline, lihat dokumentasi untuk fungsi Trace, dan ringkasan pelacakan sistem.

Memperhatikan masalah umum

Bagian ini membahas beberapa masalah yang kerap memengaruhi performa startup aplikasi. Masalah ini terutama menyangkut inisialisasi objek aplikasi dan aktivitas, serta pemuatan layar.

Menginisialisasi aplikasi berat

Performa peluncuran dapat terpengaruh jika kode Anda mengganti objek Application, dan mengeksekusi pekerjaan berat atau logika yang kompleks saat menginisialisasi objek tersebut. Aplikasi dapat membuang waktu selama startup jika subclass Aplikasi Anda melakukan inisialisasi yang masih belum perlu dilakukan. Beberapa inisialisasi mungkin sama sekali tidak diperlukan: misalnya, menginisialisasi informasi status untuk aktivitas utama, ketika aplikasi telah benar-benar dimulai oleh suatu intent. Dengan intent, aplikasi hanya menggunakan subset data status yang telah diinisialisasi sebelumnya.

Kesulitan lainnya selama inisialisasi aplikasi mencakup peristiwa pembersihan sampah memori yang paling berdampak atau sangat banyak, atau I/O disk yang terjadi bersamaan dengan inisialisasi, memblokir proses inisialisasi lebih lanjut. Pembersihan sampah memori terutama pertimbangan dengan runtime Dalvik; runtime Art yang menjalankan pembersihan sampah memori secara serentak, meminimalkan dampak operasi.

Mendiagnosis masalah

Anda dapat menggunakan metode pelacakan atau pelacakan inline untuk mendiagnosis masalahnya.

Pelacakan metode

Menjalankan CPU Profiler mengungkapkan bahwa metode callApplicationOnCreate() akhirnya memanggil metode com.example.customApplication.onCreate. Jika alat ini menunjukkan bahwa metode ini membutuhkan waktu lama untuk menyelesaikan eksekusi, sebaiknya pelajari lebih lanjut untuk melihat pekerjaan apa yang terjadi di sana.

Pelacakan inline

Gunakan pelacakan inline untuk menyelidiki kemungkinan masalah mencakup:

  • Fungsi onCreate() awal aplikasi Anda.
  • Semua objek singleton global yang diinisialisasi aplikasi.
  • Semua I/O disk, deserialisasi, atau loop ketat yang mungkin terjadi selama bottleneck.

Solusi untuk masalah tersebut

Baik masalah terletak pada inisialisasi yang tidak perlu maupun dengan I/O disk, solusinya adalah inisialisasi lambat. Dengan kata lain, Anda hanya boleh menginisialisasi objek yang langsung diperlukan. Daripada membuat objek statis global, sebaiknya pindahkan ke pola singleton tempat aplikasi menginisialisasi objek hanya saat pertama kali diperlukan.

Pertimbangkan juga untuk menggunakan dependensi framework injeksi seperti Hilt yang membuat objek dan dependensi saat melakukan injeksi untuk pertama kalinya.

Jika aplikasi Anda menggunakan penyedia konten untuk menginisialisasi komponen aplikasi saat memulai, sebaiknya gunakan library Startup Aplikasi.

Menginisialisasi aktivitas berat

Pembuatan aktivitas kerap memerlukan banyak pekerjaan overhead yang tinggi. Sering kali ada peluang untuk mengoptimalkan pekerjaan ini untuk mendapatkan peningkatan performa. Masalah umum tersebut meliputi:

  • Meluaskan tata letak yang besar atau kompleks.
  • Memblokir menggambar layar pada disk, atau I/O jaringan.
  • Memuat dan mendekode bitmap.
  • Meraster objek VectorDrawable.
  • Inisialisasi subsistem lain dari aktivitas.

Mendiagnosis masalah

Dalam hal ini, begitu juga, kedua pelacakan metode dan pelacakan inline terbukti bermanfaat.

Pelacakan metode

Saat menggunakan Profiler CPU, perhatikan konstruktor subclass Application dan metode com.example.customApplication.onCreate() dari aplikasi Anda.

Jika alat ini menunjukkan bahwa metode ini membutuhkan waktu lama dalam menyelesaikan eksekusi, sebaiknya pelajari lebih lanjutuntuk melihat pekerjaan apa yang terjadi di sana.

Pelacakan inline

Gunakan pelacakan inline untuk menyelidiki kemungkinan masalah mencakup:

  • Fungsi onCreate() awal aplikasi Anda.
  • Semua objek singleton global yang diinisialisasi olehnya.
  • Semua I/O disk, deserialisasi, atau loop ketat yang mungkin terjadi selama bottleneck.

Solusi untuk masalah tersebut

Terdapat banyak potensi bottleneck, tetapi dua masalah dan solusi umumnya adalah sebagai berikut:

  • Makin besar hierarki tampilan Anda, makin banyak waktu yang dibutuhkan aplikasi untuk meng-inflate-nya. Dua langkah yang dapat Anda lakukan untuk mengatasi masalah ini adalah:

    • Meratakan hierarki tampilan dengan mengurangi tata letak yang berlebihan atau bertingkat.

    • Tidak meng-inflate bagian dari. U. yang tidak perlu terlihat selama peluncuran. Sebagai gantinya, gunakan objek ViewStub sebagai placeholder untuk sub-hierarki yang dapat di-inflate aplikasi pada waktu yang lebih tepat.

  • Memiliki semua inisialisasi resource Anda. pada th. thread utama juga dapat memperlambat startup. Anda dapat mengatasi masalah ini seperti berikut:

    • Memindahkan semua inisialisasi resource sehingga aplikasi tersebut dapat menjalankannya dengan lambat di thread yang berbeda.
    • Mengizinkan aplikasi memuat dan menampilkan tampilan, lalu mengupdate properti visual yang bergantung pada bitmap dan resource lainnya.

Layar pembuka kustom

Anda mungkin melihat waktu tambahan yang ditambahkan selama pengaktifan jika sebelumnya telah menggunakan salah satu metode berikut untuk menerapkan layar pembuka kustom di Android 11 (API level 30) atau yang lebih rendah:

  • Menggunakan atribut tema windowDisablePreview untuk menonaktifkan layar kosong awal yang digambar oleh sistem selama peluncuran.

  • Menggunakan Aktivitas khusus

Mulai Android 12, Anda harus bermigrasi ke API SplashScreen. Dengan API ini, waktu startup dapat menjadi lebih cepat, dan juga Anda dapat menyesuaikan layar pembuka dengan cara berikut:

Selain itu, library compat dapat mem-backport SplashScreen API untuk mengaktifkan kompatibilitas mundur dan membuat tampilan serta nuansa yang konsisten untuk tampilan layar pembuka di semua versi Android.

Lihat Panduan migrasi layar pembuka untuk mengetahui detailnya.