Virtualización de datos de ListView y GridViewListView and GridView data virtualization

Nota  Para más información, consulta la sesión de //build/ Aumentar considerablemente el rendimiento cuando los usuarios interactúan con grandes cantidades de datos de GridView y ListView.Note  For more details, see the //build/ session Dramatically Increase Performance when Users Interact with Large Amounts of Data in GridView and ListView.

Mejora el rendimiento y el tiempo de inicio de las clases ListView y GridView mediante la virtualización de datos.Improve ListView and GridView performance and startup time through data virtualization. Para la virtualización de la interfaz de usuario, reducción de elementos y la actualización progresiva de elementos, consulta el tema Optimización de ListView y GridView UI.For UI virtualization, element reduction, and progressive updating of items, see ListView and GridView UI optimization.

Si dispones de un conjunto de datos que es tan grande que no se puede o no se debe almacenar en la memoria de una sola vez, necesitarás un método de virtualización de datos.A method of data virtualization is needed for a data set that is so large that it cannot or should not all be stored in memory at one time. Cargas una porción inicial en la memoria (disco local, red o nube) y aplicas la virtualización de la interfaz de usuario a este conjunto de datos parcial.You load an initial portion into memory (from local disk, network, or cloud) and apply UI virtualization to this partial data set. Más tarde, se pueden cargar datos de manera incremental o desde puntos arbitrarios del conjunto de datos maestro (acceso aleatorio) a petición.You can later load data incrementally, or from arbitrary points in the master data set (random access), on demand. Determinar si la virtualización es apropiada para tu caso depende de muchos factores.Whether data virtualization is appropriate for you depends on many factors.

  • El tamaño del conjunto de datosThe size of your data set
  • El tamaño de cada elementoThe size of each item
  • El origen del conjunto de datos (disco local, red o nube)The source of the data set (local disk, network, or cloud)
  • El consumo de memoria total de la aplicaciónThe overall memory consumption of your app

Nota  Ten en cuenta que hay una característica habilitada de manera predeterminada para ListView y GridView, que muestra objetos visuales de marcador de posición temporales mientras el usuario realiza un movimiento panorámico o desplazamiento rápidamente.Note  Be aware that a feature is enabled by default for ListView and GridView that displays temporary placeholder visuals while the user is panning/scrolling quickly. A medida que se cargan los datos, estos elementos visuales de marcador de posición se reemplazan por la plantilla de elemento.As data is loaded, these placeholder visuals are replaced with your item template. Para desactivar la característica, puedes establecer ListViewBase.ShowsScrollingPlaceholders en false, aunque si lo haces, te recomendamos que uses el atributo x:Phase para representar de manera progresiva los elementos de la plantilla de elemento.You can turn the feature off by setting ListViewBase.ShowsScrollingPlaceholders to false, but if you do so then we recommend that you use the x:Phase attribute to progressively render the elements in your item template. Consulta Actualizar los elementos ListView y GridView de forma progresiva.See Update ListView and GridView items progressively.

Aquí encontrarás más información acerca de las técnicas de virtualización de datos incremental y de acceso aleatorio.Here are more details about the incremental and random-access data virtualization techniques.

Virtualización de datos incrementalIncremental data virtualization

La virtualización de datos incremental carga los datos en secuencia.Incremental data virtualization loads data sequentially. Un ListView que usa la virtualización de datos incremental puede usarse para ver una colección de un millón de elementos, pero solo 50 elementos se cargan inicialmente.A ListView that uses incremental data virtualization may be used to view a collection of a million items, but only 50 items are loaded initially. A medida que el usuario realiza un movimiento panorámico/desplazamiento, se cargan los 50 siguientes.As the user pans/scrolls, the next 50 are loaded. A medida que se cargan los elementos, se reduce el tamaño del control de la barra de desplazamiento.As items are loaded, the scroll bar's thumb decreases in size. Para este tipo de virtualización de datos, debes escribir una clase de origen de datos que implemente estas interfaces.For this type of data virtualization you write a data source class that implements these interfaces.

Un origen de datos como el siguiente, es una lista en memoria que se puede extender continuamente.A data source like this is an in-memory list that can be continually extended. El control de elementos solicitará elementos con el indexador IList estándar y las propiedades de recuento.The items control will ask for items using the standard IList indexer and count properties. El recuento debe representar el número de elementos localmente, no el tamaño real del conjunto de datos.The count should represent the number of items locally, not the true size of the dataset.

Cuando el control de elementos se acerque al final de los datos existentes, llamará a ISupportIncrementalLoading.HasMoreItems.When the items control gets close to the end of the existing data, it will call ISupportIncrementalLoading.HasMoreItems. Si devuelves true, a continuación, llamará a ISupportIncrementalLoading.LoadMoreItemsAsync pasando un número de elementos para cargar recomendado.If you return true, then it will call ISupportIncrementalLoading.LoadMoreItemsAsync passing an advised number of items to load. Dependiendo desde dónde se están cargando datos (disco local, red o nube), puedes cargar un número diferente de elementos que el recomendado.Depending on where you're loading data from (local disk, network, or cloud), you may choose to load a different number of items than that advised. Por ejemplo, si el servicio admite lotes de 50 elementos, pero el control de elementos solo solicita 10, puede cargar 50.For example, if your service supports batches of 50 items but the items control only asks for 10 then you can load 50. Carga los datos desde el backend, agrégalos a la lista y genera una notificación de cambio a través de la interfaz INotifyCollectionChanged o IObservableVector<T> , para que el control de elementos reconozca los elementos nuevos.Load the data from your back end, add it to your list, and raise a change notification via INotifyCollectionChanged or IObservableVector<T> so that the items control knows about the new items. Asimismo, también devuelve un recuento de los elementos cargados realmente.Also return a count of the items you actually loaded. Si cargas menos elementos que lo recomendado o el control de elementos se ha movido panorámicamente/desplazado incluso más aún en el transcurso, se llamará nuevamente al origen de datos para obtener más elementos y el ciclo continuará.If you load fewer items than advised, or the items control has been panned/scrolled even further in the interim, then your data source will be called again for more items and the cycle will continue. Para obtener más información, descarga el ejemplo de enlace de datos XAML para Windows 8.1 y vuelve a usar su código fuente en tu aplicación de Windows 10.You can learn more by downloading the XAML data binding sample for Windows 8.1 and re-using its source code in your Windows 10 app.

Virtualización de datos de acceso aleatorioRandom access data virtualization

La virtualización de datos de acceso aleatorio permite cargar desde un punto arbitrario del conjunto de datos.Random access data virtualization allows loading from an arbitrary point in the data set. Un ListView que usa la virtualización de datos de acceso aleatorio, usado para ver una colección de un millón de elementos, puede cargar los elementos del 100 000 al 100 050.A ListView that uses random access data virtualization, used to view a collection of a million items, can load the items 100,000 – 100,050. Si el usuario se mueve al principio de la lista, el control carga los elementos del 1 al 50.If the user then moves to the beginning of the list, the control loads items 1 – 50. En cualquier momento, el control de la barra de desplazamiento indica que ListView contiene un millón de elementos.At all times, the scroll bar's thumb indicates that the ListView contains a million items. El control de posición de la barra de desplazamiento se ubica en relación con el lugar donde se encuentran los elementos visibles en el conjunto de datos completo de la colección.The position of the scroll bar's thumb is relative to where the visible items are located in the collection's entire data set. Este tipo de virtualización de datos puede reducir significativamente los requisitos de memoria y los tiempos de carga de la colección.This type of data virtualization can significantly reduce the memory requirements and load times for the collection. Para habilitarla, debes escribir una clase de origen de datos que recupere los datos a petición y administre una memoria caché local e implemente estas interfaces.To enable it you need to write a data source class that fetches data on demand and manages a local cache and implements these interfaces.

IItemsRangeInfo proporciona información sobre los elementos que el control está usando activamente.IItemsRangeInfo provides information on which items the control is actively using. El control de elementos llamará a este método siempre que cambie su vista e incluirá estos dos conjuntos de intervalos.The items control will call this method whenever its view is changing, and will include these two sets of ranges.

  • El conjunto de elementos que existe en la ventanilla.The set of items that are in the viewport.
  • Un conjunto de elementos no virtualizados que está usando el control que puede que no estén en la ventanilla.A set of non-virtualized items that the control is using that may not be in the viewport.
    • Un búfer de elementos de la ventanilla que el control de elementos mantiene para que el movimiento panorámico táctil sea suave.A buffer of items around the viewport that the items control keeps so that touch panning is smooth.
    • El elemento especificado.The focused item.
    • El primer elemento.The first item.

Al implementar IItemsRangeInfo, el origen de datos sabe qué elementos deben capturarse y almacenarse en caché, y cuándo eliminarse de los datos de caché que ya no son necesarios.By implementing IItemsRangeInfo your data source knows what items need to be fetched and cached, and when to prune from the cache data that is no longer needed. IItemsRangeInfo usa objetos ItemIndexRange para describir un conjunto de elementos en función de su índice de la colección.IItemsRangeInfo uses ItemIndexRange objects to describe a set of items based on their index in the collection. Esto permite evitar que se usen punteros de elemento, que podrían no ser correctos o estables.This is so that it doesn't use item pointers, which may not be correct or stable. IItemsRangeInfo está diseñado para usarse en una sola instancia de un control de elementos, porque se basa en la información de estado para ese control de elementos.IItemsRangeInfo is designed to be used by only a single instance of an items control because it relies on state information for that items control. Si varios controles de elementos necesitan acceso a los mismos datos, necesitarás una instancia por separado del origen de datos para cada uno.If multiple items controls need access to the same data then you will need a separate instance of the data source for each. Pueden compartir una memoria caché común, pero la lógica de depuración de la caché será más complicada.They can share a common cache, but the logic to purge from the cache will be more complicated.

Esta es la estrategia básica para el origen de datos de la virtualización de datos de acceso aleatorio.Here's the basic strategy for your random access data virtualization data source.

  • Cuando se solicite un elementoWhen asked for an item
    • Si está disponible en la memoria, devuélvelo.If you have it available in memory, then return it.
    • Si no lo está, devuelve null o un elemento de marcador de posición.If you don’t have it, then return either null or a placeholder item.
    • Usa la solicitud de un elemento (o la información del rango de IItemsRangeInfo) para saber qué elementos son necesarios y para capturar datos de los elementos del backend de forma asincrónica.Use the request for an item (or the range information from IItemsRangeInfo) to know which items are needed, and to fetch data for items from your back end asynchronously. Después de recuperar los datos, genera una notificación de cambio a través de INotifyCollectionChanged o IObservableVector<T> para que el control de elementos sepa del nuevo elemento.After retrieving the data, raise a change notification via INotifyCollectionChanged or IObservableVector<T> so that the items control knows about the new item.
  • (Opcionalmente) A medida que la ventanilla del control de elementos cambia, identifica qué elementos son necesarios del origen de datos a través de la implementación de IItemsRangeInfo.(Optionally) as the items control's viewport changes, identify what items are needed from your data source via your implementation of IItemsRangeInfo.

Asimismo, la estrategia de cuándo cargar elementos de datos, la cantidad de carga y qué elementos mantener en memoria depende de tu aplicación.Beyond that, the strategy for when to load data items, how many to load, and which items to keep in memory is up to your application. Algunas consideraciones generales que se deben tener en cuenta:Some general considerations to keep in mind:

  • Realiza solicitudes asincrónicas para datos; no bloquees el subproceso de la interfaz de usuario.Make asynchronous requests for data; don't block the UI thread.
  • Encuentra el punto óptimo en el tamaño de los lotes en los que capturas elementos.Find the sweet spot in the size of the batches you fetch items in. Se recomienda que sea más grande que pequeño.Prefer chunky to chatty. No tan pequeña que realizas demasiadas solicitudes pequeñas; ni tan grande que tarda demasiado tiempo en recuperarse.Not so small that you make too many small requests; not too large that they take too long to retrieve.
  • Considera la posibilidad de cuántas solicitudes que desees tener pendientes al mismo tiempo.Consider how many requests you want to have pending at the same time. Realizar una a la vez es más fácil, pero puede ser demasiado lento si el tiempo de procesamiento es alto.Performing one at a time is easier, but it may be too slow if turnaround time is high.
  • ¿Puedes cancelar las solicitudes de datos?Can you cancel requests for data?
  • Si usas un servicio hospedado, ¿existe un costo por transacción?If using a hosted service, is there a cost per transaction?
  • ¿Qué tipo de notificaciones proporciona el servicio cuando se cambian los resultados de una consulta?What kind of notifications are provided by the service when the results of a query are changed? ¿Sabrás si se inserta un elemento en el índice 33?Will you know if an item is inserted at index 33? Si el servicio admite consultas basadas en tecla-más-desplazamiento, podría ser mejor que el uso de un índice.If your service supports queries based on a key-plus-offset, that may be better than just using an index.
  • ¿Qué tan inteligente deseas ser en la captura previa elementos?How smart do you want to be in pre-fetching items? ¿Probarás realizar un seguimiento de la dirección y velocidad de desplazamiento para predecir qué elementos se necesitan?Are you going to try and track the direction and velocity of scrolling to predict which items are needed?
  • ¿Con qué dinamismo quieres purgar la memoria caché?How aggressive do you want to be in purging the cache? Esto es un equilibrio entre el uso de la memoria frente a la experiencia.This is a tradeoff of memory versus experience.