Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Analisis Aplikasi adalah alat yang memberi pengembang pemberitahuan tentang masalah performa. Analisis Aplikasi menjalankan kode aplikasi Anda terhadap serangkaian pedoman performa dan praktik terbaik.
Analisis Aplikasi mengidentifikasi masalah dari seperangkat aturan masalah performa umum yang dihadapi aplikasi. Jika sesuai, analisis aplikasi akan menunjuk ke alat garis waktu, informasi sumber, dan dokumentasi Visual Studio untuk memberi Anda sarana untuk menyelidiki.
Aturan dalam Analisis Aplikasi mengacu pada pedoman atau praktik terbaik yang sedang diperiksa oleh aplikasi Anda.
Ukuran gambar yang didekodekan lebih besar dari ukuran render
Gambar diambil pada resolusi yang sangat tinggi, yang dapat menyebabkan aplikasi menggunakan lebih banyak CPU saat mendekode data gambar dan lebih banyak memori setelah dimuat dari disk. Tetapi tidak ada gunanya mendekode dan menyimpan gambar resolusi tinggi dalam memori hanya untuk menampilkannya lebih kecil dari ukuran aslinya. Sebagai gantinya, buat versi gambar pada ukuran yang tepat akan digambar di layar menggunakan properti DecodePixelWidth dan DecodePixelHeight.
Dampak
Menampilkan gambar pada ukuran non-aslinya dapat berdampak negatif pada waktu CPU (karena pendekodean ke ukuran dan waktu pengunduhan yang tepat) dan memori.
Penyebab dan solusi
Gambar tidak diatur secara asinkron
Aplikasi menggunakan SetSource() alih-alih SetSourceAsync(). Anda harus selalu menghindari penggunaan SetSource dan sebagai gantinya menggunakan SetSourceAsync saat mengatur aliran untuk mendekode gambar secara asinkron.
Gambar dipanggil ketika ImageSource tidak berada dalam struktur aktif
BitmapImage terhubung ke pohon XAML langsung setelah mengatur konten dengan SetSourceAsync atau UriSource. Anda harus selalu melampirkan BitmapImage ke pohon aktif sebelum menetapkan sumbernya. Setiap kali elemen gambar atau kuas ditentukan dalam markup, ini akan secara otomatis terjadi. Contoh disediakan di bawah ini.
Contoh pohon hidup
Contoh 1 (baik)—Pengidentifikasi Sumber Daya Seragam (URI) yang ditentukan dalam markup.
<Image x:Name="myImage" UriSource="Assets/cool-image.png"/>
Contoh 2 markup—URI yang ditentukan dalam code-behind.
<Image x:Name="myImage"/>
Contoh 2 code-behind (baik)—menyambungkan BitmapImage ke pohon sebelum mengatur UriSource-nya.
var bitmapImage = new BitmapImage();
myImage.Source = bitmapImage;
bitmapImage.UriSource = new URI("ms-appx:///Assets/cool-image.png", UriKind.RelativeOrAbsolute);
Contoh 2 code-behind (buruk)—mengatur UriSource BitmapImage sebelum menyambungkannya ke pohon.
var bitmapImage = new BitmapImage();
bitmapImage.UriSource = new URI("ms-appx:///Assets/cool-image.png", UriKind.RelativeOrAbsolute);
myImage.Source = bitmapImage;
Kuas gambar tidak persegi panjang
Ketika gambar digunakan untuk kuas berbentuk non-persegi panjang, gambar tersebut akan diproses melalui jalur rasterisasi perangkat lunak, yang tidak akan melakukan skala gambar sama sekali. Selain itu, ia harus menyimpan salinan gambar di memori perangkat lunak dan perangkat keras. Misalnya, jika gambar digunakan sebagai kuas untuk elips, gambar utuh yang mungkin berukuran besar akan disimpan dua kali di dalam sistem. Saat menggunakan kuas yang bukan persegi panjang, aplikasi Anda harus menskalakan gambarnya sebelumnya ke ukuran yang kurang lebih sama dengan saat dirender.
Atau, Anda dapat mengatur ukuran dekode eksplisit untuk membuat versi gambar pada ukuran yang tepat akan ditampilkan di layar menggunakan properti DecodePixelWidth dan DecodePixelHeight.
<Image>
<Image.Source>
<BitmapImage UriSource="ms-appx:///Assets/highresCar.jpg"
DecodePixelWidth="300" DecodePixelHeight="200"/>
</Image.Source>
</Image>
Unit-unit untuk DecodePixelWidth dan DecodePixelHeight secara default adalah piksel fisik. Properti
Dalam beberapa kasus di mana ukuran dekode yang sesuai tidak dapat ditentukan sebelumnya, Anda harus mempercayakan pada dekoding ukuran otomatis XAML, yang akan berusaha sebaik mungkin untuk mendekode gambar pada ukuran yang tepat jika DecodePixelWidth/DecodePixelHeight secara eksplisit tidak ditentukan.
Anda harus mengatur ukuran dekode eksplisit jika Anda mengetahui ukuran konten gambar sebelumnya. Anda juga harus mengatur secara bersamaan DecodePixelType ke Logical jika ukuran dekode yang disediakan relatif terhadap ukuran elemen XAML lainnya. Misalnya, jika Anda secara eksplisit mengatur ukuran konten dengan Image.Width dan Image.Height, Anda dapat mengatur DecodePixelType ke DecodePixelType.Logical untuk menggunakan dimensi piksel logis yang sama sebagai kontrol Gambar, lalu secara eksplisit menggunakan BitmapImage.DecodePixelWidth dan/atau BitmapImage.DecodePixelHeight untuk mengontrol ukuran gambar untuk mencapai penghematan memori yang berpotensi besar.
Perhatikan bahwa Image.Stretch harus dipertimbangkan saat menentukan ukuran konten yang didekodekan.
Gambar yang digunakan di dalam BitmapIcons akan secara otomatis dideskripsikan ulang ke ukuran aslinya.
Atur ukuran dekode eksplisit untuk membuat versi gambar pada ukuran yang tepat yang akan digambar di layar dengan tepat dengan menggunakan properti DecodePixelWidth dan DecodePixelHeight.
Gambar yang tampak sangat besar pada layar akan dikembalikan ke proses dekoding dengan ukuran asli.
Gambar yang tampak sangat besar pada layar akan dikembalikan ke ukuran alami. Atur ukuran dekode eksplisit untuk membuat versi gambar pada ukuran yang tepat yang akan digambar di layar dengan tepat dengan menggunakan properti DecodePixelWidth dan DecodePixelHeight.
Gambar disembunyikan
Gambar disembunyikan dengan mengatur Opacity ke 0 atau Visibility ke Tersembunyi pada elemen gambar host, kuas, atau elemen induk mana pun. Gambar yang tidak terlihat di layar karena kliping atau transparansi mungkin akan kembali didekode ke ukuran aslinya.
Gambar menggunakan properti NineGrid
Ketika gambar digunakan untuk NineGrid, gambar akan menggunakan lintasan rasterisasi perangkat lunak, yang tidak akan mengubah ukuran gambar sama sekali. Selain itu, ia harus menyimpan salinan gambar di memori perangkat lunak dan perangkat keras. Saat menggunakan NineGrid, aplikasi Anda harus mengubah ukuran gambar terlebih dahulu mendekati ukuran saat akan dirender.
Gambar yang menggunakan properti NineGrid akan didekode ulang ke ukuran alami. Pertimbangkan untuk menambahkan efek ninegrid ke gambar asli.
DecodePixelWidth atau DecodePixelHeight diatur ke ukuran yang lebih besar dari gambar akan muncul di layar
Jika DecodePixelWidth/Height secara eksplisit diatur lebih besar daripada gambar yang akan ditampilkan di layar, aplikasi akan menggunakan memori tambahan yang tidak perlu, hingga 4 byte per piksel, yang dengan cepat menjadi mahal untuk gambar besar. Gambar juga akan diturunkan skalanya menggunakan penskalaan bilinear, yang dapat menyebabkannya tampak buram untuk faktor skala besar.
Gambar didekodekan sebagai bagian dari memproduksi gambar Seret dan Letakkan
Atur ukuran dekode eksplisit untuk membuat versi gambar pada ukuran yang tepat yang akan digambar di layar dengan tepat dengan menggunakan properti DecodePixelWidth dan DecodePixelHeight.
Elemen yang diciutkan saat pemuatan
Pola umum dalam aplikasi adalah menyembunyikan elemen di UI pada awalnya dan menunjukkannya di lain waktu. Dalam kebanyakan kasus, elemen-elemen ini harus ditangguhkan menggunakan x:Load atau x:DeferLoadStrategy untuk menghindari membayar biaya pembuatan elemen pada waktu pemuatan.
Ini termasuk kasus di mana pengonversi boolean ke visibilitas digunakan untuk menyembunyikan item hingga waktu yang akan datang.
Dampak
Elemen yang dilipat dimuat bersama elemen lain dan berkontribusi pada peningkatan waktu muat.
Penyebab
Aturan ini dipicu karena elemen diciutkan pada waktu pemuatan. Menciutkan elemen, atau mengatur opasitasnya ke 0, tidak mencegah elemen dibuat. Aturan ini dapat disebabkan oleh aplikasi yang menggunakan pengonversi visibilitas dari Boolean yang secara default diatur ke false.
Solusi
Dengan menggunakan atribut x:Load atau x:DeferLoadStrategy, Anda dapat menunda pemuatan sepotong UI, dan memuatnya saat diperlukan. Ini adalah cara yang baik untuk memperlambat pemrosesan UI yang tidak tampak dalam frame pertama. Anda dapat memilih untuk memuat elemen saat diperlukan, atau sebagai bagian dari sekumpulan logika yang tertunda. Untuk memicu pemuatan, panggil findName pada elemen yang ingin Anda muat. x:Load memperluas kemampuan x:DeferLoadStrategy yang memungkinkan elemen dapat dicopot, sehingga status pemuatan dapat dikontrol melalui x:Bind.
Dalam beberapa kasus, menggunakan findName untuk menampilkan sepotong UI mungkin bukan jawabannya. Ini benar jika Anda ingin menjadikan bagian penting dari antarmuka pengguna (UI) terwujud saat tombol diklik dengan latensi yang sangat rendah. Dalam hal ini, Anda mungkin ingin menukar pengurangan latensi UI dengan penggunaan memori tambahan, jika demikian, Anda harus menggunakan x:DeferLoadStrategy dan mengatur Visibilitas ke Tersembunyi pada elemen yang ingin Anda tampilkan. Setelah halaman dimuat dan utas UI tidak sibuk, Anda bisa memanggil findName bila perlu untuk memuat elemen. Elemen tidak akan terlihat oleh pengguna sampai Anda mengatur Visibilitas elemen ke Terlihat.
ListView tidak divirtualisasi
Virtualisasi UI adalah peningkatan terpenting yang dapat Anda lakukan untuk meningkatkan performa pengumpulan. Ini berarti bahwa elemen UI yang mewakili item dibuat sesuai permintaan. Untuk kontrol item yang terikat ke koleksi 1000 item, itu akan menjadi buang-buang sumber daya untuk membuat UI untuk semua item secara bersamaan karena tidak semuanya dapat ditampilkan pada saat yang sama. ListView dan GridView (dan kontrol turunan ItemsControl standar lainnya) melakukan virtualisasi UI untuk Anda. Ketika item hampir digulir ke tampilan (beberapa halaman menjauh), kerangka kerja menghasilkan UI untuk item dan menyimpannya dalam cache. Ketika tidak mungkin item akan ditampilkan lagi, kerangka kerja mengklaim ulang memori.
Virtualisasi UI hanyalah salah satu dari beberapa faktor utama untuk meningkatkan performa pengumpulan. Mengurangi kompleksitas item pengumpulan dan virtualisasi data adalah dua aspek penting lainnya untuk meningkatkan performa pengumpulan. Untuk informasi selengkapnya tentang meningkatkan performa koleksi dalam ListViews dan GridViews, lihat artikel tentang pengoptimalan UI ListView dan GridView dan virtualisasi data ListView dan GridViews.
Dampak
ItemsControl yang tidak divirtualisasi akan meningkatkan waktu muat dan penggunaan sumber daya dengan memuat lebih banyak item turunannya daripada yang diperlukan.
Penyebab
Konsep viewport sangat penting untuk virtualisasi UI karena kerangka kerja harus membuat elemen yang kemungkinan akan ditampilkan. Secara umum, viewport dari ItemsControl mencakup keseluruhan kontrol logis. Misalnya, viewport dari ListView adalah lebar dan tinggi elemen ListView. Beberapa panel memungkinkan elemen anak memiliki ruang yang tidak terbatas, contohnya adalah ScrollViewer dan Grid, dengan baris atau kolom yang memiliki ukuran otomatis. Ketika ItemControl virtual ditempatkan di panel seperti itu, dibutuhkan cukup ruang untuk menampilkan semua itemnya, yang mengalahkan virtualisasi.
Solusi
Pulihkan virtualisasi dengan mengatur lebar dan tinggi pada ItemsControl yang Anda gunakan.
Utas UI diblokir atau diam selama pemuatan
Pemblokiran utas UI mengacu pada panggilan sinkron ke fungsi yang dijalankan di luar utas utama yang memblokir utas UI.
Untuk daftar lengkap praktik terbaik untuk meningkatkan performa startup aplikasi Anda, lihat praktik terbaik untuk performa startup aplikasi Anda dan menjaga utas UI tetap responsif.
Dampak
Utas UI yang terblokir atau tidak aktif selama proses pemuatan akan mencegah tata letak dan operasi UI lainnya, meningkatkan waktu pemulaan aplikasi.
Penyebab
Kode platform untuk UI dan kode aplikasi Anda untuk UI semuanya dijalankan pada utas UI yang sama. Hanya satu instruksi yang dapat dijalankan pada utas tersebut pada satu waktu, jadi jika kode aplikasi Anda membutuhkan waktu terlalu lama untuk memproses peristiwa, kerangka kerja tidak dapat menjalankan tata letak atau meningkatkan peristiwa baru yang mewakili interaksi pengguna. Responsivitas aplikasi Anda terkait dengan ketersediaan utas UI untuk memproses tugas.
Solusi
Aplikasi Anda dapat interaktif meskipun ada bagian aplikasi yang tidak berfungsi penuh. Misalnya, jika aplikasi Anda menampilkan data yang membutuhkan waktu cukup lama untuk diambil, Anda dapat membuat kode tersebut dijalankan secara independen dari kode startup aplikasi dengan mengambil data secara asinkron. Saat data tersedia, isi antarmuka pengguna aplikasi dengan data. Untuk membantu menjaga aplikasi Anda tetap responsif, platform ini menyediakan versi asinkron dari banyak API-nya. API asinkron memastikan utas eksekusi aktif Anda tidak pernah terhenti dalam waktu yang lama. Saat Anda memanggil API dari utas UI, gunakan versi asinkron jika tersedia.
{Binding} sedang digunakan alih-alih {x:Bind}
Aturan ini diaktifkan saat aplikasi Anda menggunakan pernyataan {Binding}. Untuk meningkatkan performa aplikasi, aplikasi harus mempertimbangkan untuk menggunakan {x:Bind}.
Dampak
{Binding} memerlukan lebih banyak waktu dan memori daripada {x:Bind}.
Penyebab
Aplikasi menggunakan {Binding} alih-alih {x:Bind}. {Binding} membawa set kerja yang signifikan dan penambahan beban pada CPU. Membuat {Binding} menyebabkan serangkaian alokasi, dan memperbarui target pengikatan dapat menyebabkan refleksi dan pembungkusan.
Solusi
Gunakan ekstensi markup {x:Bind}, yang mengkompilasi pengikatan pada waktu build. Pengikatan {x:Bind} (sering disebut sebagai pengikatan yang dikompilasi) memiliki performa yang bagus, memberikan validasi waktu kompilasi ekspresi pengikatan Anda, dan mendukung penelusuran kesalahan dengan memungkinkan Anda mengatur titik henti dalam file kode yang dihasilkan sebagai kelas parsial untuk halaman Anda.
Perhatikan bahwa x:Bind tidak cocok dalam semua kasus seperti skenario keterikatan yang ditunda. Untuk daftar lengkap kasus yang tidak dicakup oleh {x:Bind}, lihat dokumentasi {x:Bind}.
x:Name sedang digunakan alih-alih x:Key
ResourceDictionaries umumnya digunakan untuk menyimpan sumber daya Anda pada tingkat yang agak global, yaitu sumber daya yang ingin dirujuk oleh aplikasi Anda di berbagai tempat; misalnya, gaya, kuas, templat, dan sebagainya. Secara umum, kami telah mengoptimalkan ResourceDictionaries untuk tidak membuat instans sumber daya kecuali jika diminta. Tetapi ada beberapa tempat di mana Anda harus sedikit berhati-hati.
Dampak
Sumber daya apa pun dengan x:Name akan dibuat segera setelah ResourceDictionary dibuat. Ini terjadi karena x:Name memberi tahu platform bahwa aplikasi Anda memerlukan akses bidang ke sumber daya ini, sehingga platform perlu membuat sesuatu untuk membuat referensi.
Penyebab
Aplikasi Anda mengatur x:Name pada sumber daya.
Solusi
Gunakan x:Key alih-alih x:Name saat Anda tidak mereferensikan sumber daya dari code-behind.
Pengontrolan koleksi menggunakan panel non-virtualisasi
Jika Anda menyediakan templat panel item kustom (lihat ItemsPanel), pastikan Anda menggunakan panel virtualisasi seperti ItemsWrapGrid atau ItemsStackPanel. Jika Anda menggunakan VariableSizedWrapGrid, WrapGrid, atau StackPanel, Anda tidak akan mendapatkan virtualisasi. Selain itu, peristiwa ListView berikut ini hanya dimunculkan ketika menggunakan ItemsWrapGrid atau ItemsStackPanel: MemilihGroupHeaderContainer, MemilihItemContainer, dan PerubahanKontenContainer.
Virtualisasi UI adalah peningkatan terpenting yang dapat Anda lakukan untuk meningkatkan performa pengumpulan. Ini berarti bahwa elemen UI yang mewakili item dibuat sesuai permintaan. Untuk kontrol item yang terikat ke koleksi 1000 item, itu akan menjadi buang-buang sumber daya untuk membuat UI untuk semua item secara bersamaan karena tidak semuanya dapat ditampilkan pada saat yang sama. ListView dan GridView (dan kontrol turunan ItemsControl standar lainnya) melakukan virtualisasi UI untuk Anda. Ketika item hampir digulir ke tampilan (beberapa halaman menjauh), kerangka kerja menghasilkan UI untuk item dan menyimpannya dalam cache. Ketika tidak mungkin item akan ditampilkan lagi, kerangka kerja mengklaim ulang memori.
Virtualisasi UI hanyalah salah satu dari beberapa faktor utama untuk meningkatkan performa pengumpulan. Mengurangi kompleksitas item pengumpulan dan virtualisasi data adalah dua aspek penting lainnya untuk meningkatkan performa pengumpulan. Untuk informasi selengkapnya tentang meningkatkan performa koleksi dalam ListViews dan GridViews, lihat artikel tentang pengoptimalan UI ListView dan GridView dan virtualisasi data ListView dan GridViews.
Dampak
ItemsControl yang tidak divirtualisasi akan meningkatkan waktu muat dan penggunaan sumber daya dengan memuat lebih banyak item turunannya daripada yang diperlukan.
Penyebab
Anda menggunakan panel yang tidak mendukung virtualisasi.
Solusi
Gunakan panel virtualisasi seperti ItemsWrapGrid atau ItemsStackPanel.
Aksesibilitas: Elemen UIA tanpa nama
Di XAML, Anda dapat memberikan nama dengan mengatur AutomationProperties.Name. Banyak rekan otomatisasi memberikan nama bawaan ke UIA jika AutomationProperties.Name tidak disetel.
Dampak
Jika pengguna mencapai elemen tanpa nama, mereka sering kali tidak akan tahu apa yang terkait dengan elemen tersebut.
Penyebab
Nama UIA Element null atau kosong. Aturan ini memeriksa apa yang dilihat UIA, bukan nilai AutomationProperties.Name.
Solusi
Atur properti AutomationProperties.Name di XAML kontrol ke string lokal yang sesuai.
Terkadang perbaikan aplikasi yang tepat bukan memberikan nama, melainkan menghapus elemen UIA dari semua kecuali pohon mentah. Anda dapat melakukannya di XAML dengan mengatur AutomationProperties.AccessibilityView = "Raw".
Aksesibilitas: Elemen UIA dengan Controltype yang sama tidak boleh memiliki nama yang sama
Dua elemen UIA dengan induk UIA yang sama tidak boleh memiliki Nama dan ControlType yang sama. Tidak apa-apa untuk memiliki dua kontrol dengan Nama yang sama jika mereka memiliki ControlTypes yang berbeda.
Aturan ini tidak memeriksa nama duplikat dengan orang tua yang berbeda. Namun, dalam kebanyakan kasus, Anda tidak boleh menduplikasi Nama dan ControlTypes dalam seluruh jendela, bahkan dengan orang tua yang berbeda. Kasus di mana nama duplikat dalam jendela dapat diterima adalah dua daftar dengan item yang identik. Dalam hal ini, item daftar diharapkan memiliki Nama dan ControlTypes yang identik.
Dampak
Jika pengguna mencapai elemen dengan Nama dan ControlType yang sama dengan elemen lain dengan induk UIA yang sama, pengguna mungkin tidak dapat membedakan perbedaan antara elemen.
Penyebab
Elemen UIA dengan induk UIA yang sama memiliki Nama dan ControlType yang sama.
Solusi
Atur nama di XAML menggunakan AutomationProperties.Name. Dalam daftar tempat ini umumnya terjadi, gunakan pengikatan untuk mengikat nilai AutomationProperties.Name ke sumber data.