Virtualisasi data ListView dan GridView

Catatan
Untuk detail selengkapnya, lihat sesi //build/ Meningkatkan Performa Secara Dramatis saat Pengguna Berinteraksi dengan Data Dalam Jumlah Besar di GridView dan ListView.

Tingkatkan performa ListView dan GridView dan waktu mulai melalui virtualisasi data. Untuk virtualisasi UI, pengurangan elemen, dan pembaruan item secara progresif, lihat Mengoptimalkan performa ListView dan GridView untuk WinUI.

Metode virtualisasi data diperlukan untuk himpunan data yang sangat besar sehingga tidak dapat atau tidak semuanya disimpan dalam memori pada satu waktu. Anda memuat bagian awal ke dalam memori (dari disk lokal, jaringan, atau cloud) dan menerapkan virtualisasi UI ke himpunan data parsial ini. Anda nantinya dapat memuat data secara bertahap, atau dari titik arbitrer dalam himpunan data master (akses acak), sesuai permintaan. Apakah virtualisasi data sesuai untuk Anda bergantung pada banyak faktor.

  • Ukuran himpunan data Anda
  • Ukuran setiap item
  • Sumber himpunan data (disk lokal, jaringan, atau cloud)
  • Konsumsi memori keseluruhan aplikasi WinUI Anda

Catatan Ketahuilah bahwa fitur diaktifkan secara default untuk ListView dan GridView yang menampilkan visual tempat penampung sementara saat pengguna menggeser atau menggulir dengan cepat. Saat data dimuatkan, visual sementara ini diganti dengan templat item Anda. Anda dapat menonaktifkan fitur dengan mengatur ListViewBase.ShowsScrollingPlaceholders ke false, tetapi jika Anda melakukannya, kami sarankan Anda menggunakan atribut x:Phase untuk merender elemen secara progresif dalam templat item Anda. Lihat Memperbarui item ListView dan GridView secara progresif.

Berikut adalah detail selengkapnya tentang teknik virtualisasi data akses inkremental dan acak.

Virtualisasi data bertahap

Virtualisasi data inkremental memuat data secara beruntun. ListView yang menggunakan virtualisasi data inkremental dapat digunakan untuk melihat kumpulan jutaan item, tetapi hanya 50 item yang dimuat pada awalnya. Saat pengguna menggeser atau menggulir, 50 berikutnya dimuat. Saat item dimuat, ibu jari bilah gulir berkurang ukurannya. Untuk jenis virtualisasi data ini, Anda menulis kelas sumber data yang mengimplementasikan antarmuka ini.

Sumber data seperti ini adalah daftar dalam memori yang dapat terus diperluas. Kontrol item akan meminta item menggunakan pengindeks IList standar dan properti hitung. Jumlah harus mewakili jumlah item secara lokal, bukan ukuran himpunan data yang sebenarnya.

Ketika kontrol item mendekati akhir data yang ada, kontrol item memanggil ISupportIncrementalLoading.HasMoreItems. Jika Anda mengembalikan true, maka ia memanggil ISupportIncrementalLoading.LoadMoreItemsAsync, meneruskan jumlah item yang disarankan untuk dimuat. Bergantung pada tempat Anda memuat data dari (disk lokal, jaringan, atau cloud), Anda dapat memilih untuk memuat jumlah item yang berbeda dari yang disarankan. Misalnya, jika layanan Anda mendukung batch 50 item tetapi kontrol item hanya meminta 10, maka Anda dapat memuat 50. Muat data dari back end Anda, tambahkan ke daftar Anda, dan ajukan pemberitahuan perubahan melalui INotifyCollectionChanged atau IObservableVector<T> sehingga kontrol item tahu tentang item baru. Juga mengembalikan jumlah item yang benar-benar dimuat. Jika Anda memuat lebih sedikit item daripada yang disarankan, atau kontrol item telah digerakkan secara horisontal atau digulir lebih jauh selama jeda waktu, sumber data Anda akan dipanggil lagi untuk lebih banyak item dan siklus berlanjut. ISupportIncrementalLoading tetap tersedia di Windows App SDK, sehingga Anda dapat menggunakan pola pemuatan inkremental yang sama di aplikasi WinUI.

Virtualisasi data dengan akses acak

Virtualisasi data akses acak memungkinkan pemuatan dari titik sewenang-wenang dalam himpunan data. ListView yang menggunakan virtualisasi data akses acak untuk melihat kumpulan jutaan item dapat memuat item 100.000-100.050. Jika pengguna kemudian berpindah ke awal daftar, kontrol akan memuat item 1-50. Setiap saat, jempol bilah gulir menunjukkan bahwa ListView berisi satu juta item. Posisi jempol bilah gulir relatif terhadap tempat item yang terlihat berada di seluruh himpunan data koleksi. Jenis virtualisasi data ini dapat secara signifikan mengurangi persyaratan memori dan waktu muat untuk pengumpulan. Untuk mengaktifkannya, Anda perlu menulis kelas sumber data yang mengambil data sesuai permintaan, mengelola cache lokal, dan mengimplementasikan antarmuka ini.

IItemsRangeInfo menyediakan informasi tentang item mana yang digunakan kontrol secara aktif. Kontrol item memanggil metode ini setiap kali tampilannya berubah, dan menyertakan dua set rentang ini.

  • Kumpulan item yang ada di viewport.
  • Sekumpulan item yang tidak tervirtualisasi yang digunakan oleh kontrol sistem yang mungkin tidak terlihat di viewport.
    • Buffer yang terdiri dari item di sekitar viewport yang dikontrol oleh item tersebut untuk memastikan panning sentuhan tetap halus.
    • Elemen yang difokuskan.
    • Item yang pertama.

Dengan menerapkan IItemsRangeInfo, sumber data Anda tahu item apa yang perlu diambil dan di-cache, dan kapan harus memangkas data dari cache yang tidak lagi diperlukan. IItemsRangeInfo menggunakan objek ItemIndexRange untuk menjelaskan sekumpulan item berdasarkan indeksnya dalam koleksi. Untuk menghindari penunjuk item yang mungkin tidak benar atau stabil. IItemsRangeInfo dirancang untuk digunakan hanya oleh satu instans kontrol item karena bergantung pada informasi status untuk kontrol item tersebut. Jika beberapa kontrol item memerlukan akses ke data yang sama, maka Anda memerlukan instans terpisah dari sumber data untuk masing-masing item. Mereka dapat berbagi cache umum, tetapi logika untuk menghapus dari cache akan lebih rumit. IItemsRangeInfo tetap tersedia di Windows App SDK, sehingga teknik caching akses langsung yang sama berlaku untuk komponen WinUI.

Berikut adalah strategi dasar untuk sumber data virtualisasi akses acak Anda.

  • Ketika diminta barang
    • Jika Anda memilikinya tersimpan dalam memori, maka kembalikan itu.
    • Jika Anda tidak memilikinya, kembalikan salah satu null atau item placeholder.
    • Gunakan permintaan item (atau informasi rentang dari IItemsRangeInfo) untuk mengetahui item mana yang diperlukan, dan untuk mengambil data item dari sistem back end Anda secara asinkron. Setelah mengambil data, ajukan pemberitahuan perubahan melalui INotifyCollectionChanged atau IObservableVector<T> sehingga kontrol item tahu tentang item baru.
  • (Opsional) saat viewport kontrol item berubah, identifikasi item apa yang diperlukan dari sumber data Anda melalui implementasi IItemsRangeInfo Anda.

Di luar itu, strategi kapan harus memuat item data, berapa banyak yang harus dimuat, dan item mana yang harus disimpan dalam memori hingga aplikasi Anda. Beberapa pertimbangan umum yang perlu diingat:

  • Buat permintaan asinkron untuk data; jangan memblokir utas UI.
  • Temukan ukuran kelompok paling ideal untuk memproses item. Lebih suka yang padat daripada yang bertele-tele. Tidak begitu kecil sehingga Anda membuat terlalu banyak permintaan kecil; tidak begitu besar sehingga membutuhkan waktu terlalu lama untuk mengambilnya.
  • Pertimbangkan berapa banyak permintaan yang ingin Anda miliki dalam status menunggu pada saat yang sama. Melakukan satu per satu lebih mudah, tetapi mungkin terlalu lambat jika waktu penyelesaian tinggi.
  • Dapatkah Anda membatalkan permintaan data?
  • Jika menggunakan layanan yang dihosting, apakah ada biaya per transaksi?
  • Jenis pemberitahuan apa yang disediakan oleh layanan saat hasil kueri berubah? Akankah Anda tahu apakah item disisipkan pada indeks 33? Jika layanan Anda mendukung kueri berdasarkan kunci-plus-offset, itu mungkin lebih baik daripada hanya menggunakan indeks.
  • Seberapa cerdas Anda ingin dalam melakukan prefetching item? Apakah Anda akan mencoba melacak arah dan kecepatan gulir untuk memprediksi item mana yang diperlukan?
  • Seberapa agresif Anda ingin membersihkan cache? Ini adalah kompromi antara memori dan pengalaman.