Freigeben über


Virtualisierung von ListView- und GridView-Daten

Hinweis
Weitere Informationen finden Sie in der //build/-Sitzung zum Thema "Dramatisch verbesserte Leistung bei der Interaktion mit großen Datenmengen in GridView und ListView".

Verbessern Sie die Leistung von ListView und GridView und die Startzeit durch die Datenvirtualisierung. Informationen zur Ui-Virtualisierung, Elementreduzierung und progressiven Aktualisierung von Elementen finden Sie unter Optimieren der Leistung von ListView und GridView für WinUI.

Eine Methode der Datenvirtualisierung ist für einen Datensatz erforderlich, der so groß ist, dass er nicht alle gleichzeitig im Arbeitsspeicher gespeichert werden kann oder sollte. Sie laden einen anfänglichen Teil in den Arbeitsspeicher (vom lokalen Datenträger, netzwerk oder in der Cloud) und wenden die UI-Virtualisierung auf diesen teiligen Datensatz an. Sie können Daten später inkrementell oder von beliebigen Punkten im Masterdatensatz (zufälliger Zugriff) bei Bedarf laden. Ob die Datenvirtualisierung für Sie geeignet ist, hängt von vielen Faktoren ab.

  • Die Größe Ihres Datasets
  • Die Größe der einzelnen Elemente
  • Die Quelle des Datasets (lokaler Datenträger, Netzwerk oder Cloud)
  • Der gesamtspeicherverbrauch Ihrer WinUI-App

Hinweis Beachten Sie, dass für ListView und GridView standardmäßig ein Feature aktiviert ist, das temporäre Platzhalterelemente anzeigt, während der Benutzer schnell schwenkt oder scrollt. Wenn Daten geladen werden, werden diese Platzhalterelemente durch Ihre Elementvorlage ersetzt. Sie können das Feature deaktivieren, indem Sie ListViewBase.ShowsScrollingPlaceholders auf "false" festlegen. Wenn Sie dies tun, empfiehlt es sich jedoch, das x:Phase-Attribut zu verwenden, um die Elemente in Ihrer Elementvorlage schrittweise zu rendern. Weitere Informationen finden Sie unter "Elemente von ListView und GridView schrittweise aktualisieren".

Hier sind weitere Details zu den inkrementellen und zufälligen Datenvirtualisierungstechniken.

Inkrementelle Datenvirtualisierung

Inkrementelle Datenvirtualisierung lädt Daten sequenziell. Eine ListView , die inkrementelle Datenvirtualisierung verwendet, kann verwendet werden, um eine Sammlung von millionen Elementen anzuzeigen, aber es werden anfänglich nur 50 Elemente geladen. Beim Schwenken oder Scrollen des Benutzers werden die nächsten 50 geladen. Wenn Elemente geladen werden, verringert sich der Daumen der Bildlaufleiste in der Größe. Für diesen Typ der Datenvirtualisierung schreiben Sie eine Datenquellenklasse, die diese Schnittstellen implementiert.

Eine Datenquelle wie dies ist eine Speicherliste, die kontinuierlich erweitert werden kann. Das Elementsteuerelement fordert Elemente mithilfe der standardmäßigen IList-Indexer- und Anzahleigenschaften an. Die Anzahl sollte die Anzahl der Elemente lokal und nicht die tatsächliche Größe des Datasets darstellen.

Wenn sich das Elementsteuerelement dem Ende der vorhandenen Daten nähert, ruft es ISupportIncrementalLoading.HasMoreItems auf. Wenn Sie "true" zurückgeben, wird " ISupportIncrementalLoading.LoadMoreItemsAsync" aufgerufen, wobei eine empfohlene Anzahl der zu ladenden Elemente übergeben wird. Je nachdem, von wo Sie Daten laden (lokaler Datenträger, Netzwerk oder Cloud), können Sie eine andere Anzahl von Elementen laden als empfohlen. Wenn Ihr Dienst beispielsweise Batches von 50 Elementen unterstützt, das Elementsteuerelement jedoch nur 10 anfragt, können Sie 50 laden. Laden Sie die Daten aus Ihrem Back-End, fügen Sie sie zu Ihrer Liste hinzu, und lösen Sie eine Änderungsbenachrichtigung über INotifyCollectionChanged oder IObservableVector<T> aus, damit das Elementsteuerelement über die neuen Elemente informiert ist. Gibt auch die Anzahl der Elemente zurück, die Sie tatsächlich geladen haben. Wenn Sie weniger Elemente laden als empfohlen oder wenn das Steuerungselement verschoben oder weiter gescrollt wird, wird die Datenquelle erneut für weitere Elemente aufgerufen, und der Vorgang wiederholt sich. ISupportIncrementalLoading bleibt im Windows App SDK verfügbar, sodass Sie dasselbe inkrementelle Lademuster in einer WinUI-App verwenden können.

Datenvirtualisierung mit wahllosem Zugriff

Die Datenvirtualisierung mit wahllosem Zugriff ermöglicht das Laden von einem beliebigen Punkt im Dataset. Eine ListView, die die Datenvirtualisierung mit wahlfreiem Zugriff verwendet, um eine Sammlung von einer Million Elementen anzuzeigen, kann Elemente im Bereich von 100.000 bis 100.050 laden. Wenn der Benutzer dann zum Anfang der Liste wechselt, lädt das Steuerelement die Elemente 1 bis 50. Immer gibt der Daumen der Bildlaufleiste an, dass die ListView eine Million Elemente enthält. Die Position des Schiebereglers der Bildlaufleiste ist relativ zur Position der sichtbaren Elemente im gesamten Datensatz der Auflistung. Diese Art der Datenvirtualisierung kann die Speicheranforderungen und Ladezeiten für die Sammlung erheblich reduzieren. Um dies zu ermöglichen, müssen Sie eine Datenquellenklasse schreiben, die Daten bei Bedarf abruft, einen lokalen Cache verwaltet und diese Schnittstellen implementiert.

IItemsRangeInfo stellt Informationen darüber bereit, welche Elemente das Steuerelement aktiv verwendet. Das Elementsteuerelement ruft diese Methode immer dann auf, wenn sich die Ansicht ändert, und schließt diese beiden Bereichssätze ein.

  • Der Satz von Elementen, die sich im Viewport befinden.
  • Eine Reihe nicht virtualisierter Elemente, die das Steuerelement verwendet, das sich möglicherweise nicht im Viewport befindet.
    • Ein Puffer von Elementen um den Viewport, den das Elementsteuerelement behält, sodass die Touchverschiebung reibungslos ist.
    • Das fokussierte Element.
    • Das erste Element.

Durch die Implementierung von IItemsRangeInfo weiß Ihre Datenquelle, welche Elemente abgerufen und zwischengespeichert werden müssen, und wann Daten aus dem Cache gelöscht werden müssen, der nicht mehr benötigt wird. IItemsRangeInfo verwendet ItemIndexRange-Objekte , um eine Gruppe von Elementen basierend auf ihrem Index in der Auflistung zu beschreiben. Dadurch werden Elementzeiger vermieden, die möglicherweise nicht korrekt oder stabil sind. IItemsRangeInfo ist dafür ausgelegt, nur von einer einzelnen Instanz eines Elementsteuerelements verwendet zu werden, weil es auf Zustandsinformationen dieses Elementsteuerelements angewiesen ist. Wenn mehrere Elementsteuerelemente Zugriff auf dieselben Daten benötigen, benötigen Sie jeweils eine separate Instanz der Datenquelle. Sie können einen gemeinsamen Cache freigeben, aber die Logik zum Löschen aus dem Cache ist komplizierter. IItemsRangeInfo bleibt im Windows App SDK verfügbar, sodass die gleichen Methoden für die Zwischenspeicherung des zufälligen Zugriffs auf WinUI-Steuerelemente gelten.

Hier ist die grundlegende Strategie für Ihre Datenquelle zur Datenvirtualisierung mit zufälligem Zugriff.

  • Wenn Sie nach einem Element gefragt werden
    • Wenn sie im Arbeitsspeicher verfügbar ist, geben Sie sie zurück.
    • Wenn Sie dies nicht haben, geben Sie entweder null oder ein Platzhalterelement zurück.
    • Verwenden Sie die Anforderung für ein Element (oder die Bereichsinformationen von IItemsRangeInfo), um zu wissen, welche Elemente erforderlich sind, und um Daten für Elemente asynchron vom Back-End abzurufen. Nachdem Sie die Daten abgerufen haben, lösen Sie eine Änderungsbenachrichtigung über INotifyCollectionChanged oder IObservableVector<T> aus, damit das Elementsteuerelement über das neue Element informiert ist.
  • (Optional) Wenn sich der Viewport des Elementsteuerelements ändert, identifizieren Sie, welche Elemente aus Ihrer Datenquelle über die Implementierung von IItemsRangeInfo benötigt werden.

Darüber hinaus liegt die Strategie, wann Datenelemente geladen werden sollen, wie viele geladen werden sollen und welche Elemente im Arbeitsspeicher gespeichert werden sollen, in der Verantwortung Ihrer Anwendung. Einige allgemeine Überlegungen, die Sie berücksichtigen sollten:

  • Asynchrone Anforderungen für Daten stellen; blockieren Sie den UI-Thread nicht.
  • Finden Sie die optimale Größe der Stapel zum Abrufen von Elementen. "Bevorzugen Sie klobige statt geschwätzige Strukturen." Nicht so klein, dass Sie zu viele kleine Anfragen stellen; nicht so groß, dass sie zu lange dauern, um sie abzurufen.
  • Überlegen Sie, wie viele Anforderungen gleichzeitig ausstehen sollen. Die Ausführung jeweils einer Aufgabe ist einfacher, aber sie kann zu langsam sein, wenn die Bearbeitungsdauer hoch ist.
  • Können Sie Datenanforderungen abbrechen?
  • Wenn Sie einen gehosteten Dienst verwenden, gibt es kosten pro Transaktion?
  • Welche Art von Benachrichtigungen werden vom Dienst bereitgestellt, wenn sich die Ergebnisse einer Abfrage ändern? Wissen Sie, ob ein Element bei Index 33 eingefügt wird? Wenn Ihr Dienst Abfragen basierend auf einem Schlüssel-Plus-Offset unterstützt, ist dies möglicherweise besser als die Verwendung eines Indexes.
  • Wie möchten Sie intelligent beim Vorabrufen von Elementen sein? Versuchen Sie, die Richtung und Geschwindigkeit des Bildlaufs nachzuverfolgen, um vorherzusagen, welche Elemente erforderlich sind?
  • Wie aggressiv möchten Sie den Cache bereinigen? Dies ist ein Kompromiss zwischen Speicher und Erfahrung.