Virtualizace dat ListView a GridView

Poznámka
Další podrobnosti najdete v relaci //build/ Zvýšit dramaticky výkon při interakci uživatelů s velkými objemy dat v GridView a ListView.

Vylepšení výkonu a doby spouštění Objektu ListView a GridView prostřednictvím virtualizace dat Informace o virtualizaci uživatelského rozhraní, redukci prvků a postupné aktualizaci položek najdete v tématu Optimalizace výkonu ListView a GridView pro WinUI.

Metoda virtualizace dat je potřebná pro sadu dat, která je tak velká, že nemůže nebo by neměla být uložena v paměti najednou. Načtete počáteční část do paměti (z místního disku, sítě nebo cloudu) a použijete virtualizaci uživatelského rozhraní pro tuto částečnou datovou sadu. Později můžete načíst data přírůstkově nebo z libovolných bodů v hlavní sadě dat (náhodný přístup) na vyžádání. To, jestli je virtualizace dat vhodná pro vás, závisí na mnoha faktorech.

  • Velikost datové sady
  • Velikost každé položky
  • Zdroj datové sady (místní disk, síť nebo cloud)
  • Celková spotřeba paměti aplikace WinUI

Poznámka Mějte na paměti, že funkce je ve výchozím nastavení povolena pro ListView a GridView, které zobrazují dočasné zástupné vizuály, zatímco uživatel rychle posouvá nebo skroluje. Při načítání dat se tyto zástupné vizuály nahradí šablonou položky. Funkci můžete vypnout nastavením ListViewBase.ShowsScrollingPlaceholders na false, ale pokud to uděláte, doporučujeme použít atribut x:Phase k postupnému vykreslení prvků v šabloně položky. Podívejte se na postupnou aktualizaci položek ListView a GridView.

Tady jsou další podrobnosti o technikách virtualizace dat pro přírůstkový a náhodný přístup.

Přírůstková virtualizace dat

Přírůstková virtualizace dat načítá data postupně. ListView, který používá přírůstkovou virtualizaci dat, se může použít k zobrazení kolekce milionů položek, ale zpočátku se načtou pouze 50 položek. Při posunu nebo rolování uživatelem se načte dalších 50. Při načítání položek se palec posuvníku zmenší. Pro tento typ virtualizace dat napíšete třídu zdroje dat, která implementuje tato rozhraní.

Takový zdroj dat je seznam v paměti, který se dá průběžně rozšiřovat. Ovládací prvek Items bude požadovat položky pomocí standardního indexeru IList a vlastností počtu. Počet by měl představovat počet položek místně, nikoli skutečnou velikost datové sady.

Když se ovládací prvek items blíží ke konci existujících dat, volá ISupportIncrementalLoading.HasMoreItems. Pokud vrátíte true, zavolá ISupportIncrementalLoading.LoadMoreItemsAsync a předá doporučený počet položek k načtení. V závislosti na tom, odkud načítáte data (místní disk, síť nebo cloud), se můžete rozhodnout načíst jiný počet položek, než kolik se doporučuje. Pokud například vaše služba podporuje dávky po 50 položkách, ale kontrola položek si vyžádá pouze 10, můžete načíst 50. Načtěte data z back-endu, přidejte je do seznamu a vytvořte oznámení o změnách prostřednictvím INotifyCollectionChanged nebo IObservableVector<T> , aby ovládací prvek položky věděl o nových položkách. Také vrátí počet položek, které byly skutečně načteny. Pokud načtete méně položek, než je doporučeno, nebo byl ovládací prvek položek posunut či posunul ještě dál, bude zdroj dat znovu dotázán pro více položek, a cyklus pokračuje. ISupportIncrementalLoading zůstává k dispozici v sadě Windows App SDK, takže můžete použít stejný vzor přírůstkového načítání v aplikaci WinUI.

Virtualizace dat náhodného přístupu

Virtualizace dat náhodného přístupu umožňuje načtení z libovolného bodu v sadě dat. ListView, který používá virtualizaci dat náhodného přístupu k zobrazení kolekce milionů položek, může načíst položky 100 000–100 050. Pokud se uživatel přesune na začátek seznamu, ovládací prvek načte položky 1–50. V každém okamžiku palec posuvníku označuje, že ListView obsahuje milion položek. Pozice palce posuvníku je relativní vzhledem k umístění viditelných položek v celé sadě dat kolekce. Tento typ virtualizace dat může výrazně snížit požadavky na paměť a dobu načítání kolekce. Pokud ho chcete povolit, musíte napsat třídu zdroje dat, která načítá data na vyžádání, spravuje místní mezipaměť a implementuje tato rozhraní.

IItemsRangeInfo poskytuje informace o tom, které položky ovládací prvek aktivně používá. Ovládací prvek items volá tuto metodu při každé změně jeho zobrazení a zahrnuje tyto dvě sady oblastí.

  • Sada položek, které jsou v oblasti zobrazení.
  • Sada ne virtualizovaných položek, které ovládací prvek používá, nemusí být v oblasti zobrazení.
    • Vyrovnávací paměť položek kolem oblasti zobrazení, kterou ovládací prvek položky udržuje, aby dotykové posouvání bylo hladké.
    • Položka s fokusem
    • První položka.

Implementací IItemsRangeInfo váš zdroj dat ví, které položky je potřeba načíst a uložit do mezipaměti, a kdy vyřadit data z mezipaměti, která už není potřeba. IItemsRangeInfo používá ItemIndexRange objekty k popisu sady položek na základě jejich indexu v kolekci. Tím se zabrání ukazatelům položek, které nemusí být správné nebo stabilní. IItemsRangeInfo je navržen tak, aby byl používán pouze jednou instancí ovládacího prvku items, protože spoléhá na informace o stavu pro tento ovládací prvek položky. Pokud více ovládacích prvků pro položky potřebuje přístup ke stejným datům, musíte mít pro každý ovládací prvek samostatnou instanci zdroje dat. Můžou sdílet společnou mezipaměť, ale logika pro vymazání z mezipaměti bude složitější. IItemsRangeInfo zůstává k dispozici v sadě Windows App SDK, takže stejné techniky ukládání do mezipaměti s náhodným přístupem platí pro ovládací prvky WinUI.

Tady je základní strategie pro zdroj dat pro virtualizaci s náhodným přístupem.

  • Při zobrazení výzvy k zadání položky
    • Pokud to máte uloženo v paměti, vraťte to.
    • Pokud to nemáte, vraťte buď null, nebo zástupnou položku.
    • Pomocí požadavku na položku (nebo informace o rozsahu z IItemsRangeInfo) zjistěte, které položky jsou potřeba, a asynchronně načtěte data pro tyto položky z vašeho serverového prostředí. Po načtení dat vytvořte oznámení o změně prostřednictvím INotifyCollectionChanged nebo IObservableVector<T> tak, aby ovládací prvek položky věděl o nové položce.
  • (Volitelně) při změně oblasti zobrazení ovládacího prvku položek určete, které položky jsou potřeba z vašeho zdroje dat prostřednictvím implementace IItemsRangeInfo.

Kromě toho je strategie, kdy načíst datové položky, kolik se má načíst a které položky, které se mají uchovávat v paměti, je v aplikaci. Některé obecné aspekty, které je potřeba vzít v úvahu:

  • Vytváření asynchronních požadavků na data; nezablokujte vlákno uživatelského rozhraní.
  • Najděte optimální velikost dávek pro načítání položek. Upřednostňuje objemné před ukecaností. Ani příliš malé, aby bylo nutné provádět mnoho drobných požadavků; ani tak velké, aby jejich načítání trvalo příliš dlouho.
  • Zvažte, kolik požadavků chcete mít současně čekající. Vykonávání jednoho po druhém je jednodušší, ale může být příliš pomalé, pokud je doba zpracování vysoká.
  • Můžete zrušit žádosti o data?
  • Pokud používáte hostovanou službu, existuje poplatek za transakci?
  • Jaký druh oznámení služba poskytuje při změně výsledků dotazu? Budete vědět, jestli je položka vložena do indexu 33? Pokud vaše služba podporuje dotazy založené na klíči a posunu, může to být lepší než použití pouze indexu.
  • Jak inteligentní chcete být v předběžném načítání položek? Pokusíte se sledovat směr a rychlost posouvání, abyste předpověděli, které položky jsou potřeba?
  • Jak agresivně chcete čistit mezipaměť? Jedná se o kompromis mezi pamětí a zkušenostmi.