Considerando el siguiente archivo XAML de muestra, que muestra las primeras 1000 personas de Facebook, comenzando con markz como 4ta persona. Tenga en cuenta que esto es solo una muestra. Cualquier ventana con elemento 1000, sin importar cómo la construyas, es una buena demostración.¿Por qué <Origen de imagen = '...'> es tan lento y qué puedo hacer al respecto?
<Window x:Class="SO.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:clr="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="350" Width="525">
<ListBox ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Window>
Y el código subyacente:
public partial class MainWindow : Window
{
public MainWindow() {
InitializeComponent();
string[] urls = new string[1000];
for (int i = 0; i < 1000; ++i) {
urls[i] = "http://graph.facebook.com/" + i + "/picture";
}
this.DataContext = urls;
}
}
En un escritorio muy razonable y conexión de alta velocidad, el programa es extremadamente lento. Tratar de desplazarse con ScrollBar ... decir al medio, tomará 30 segundos. Tocar las teclas 'Inicio' y 'Finalizar' llevará bastante tiempo.
No es un problema de primera vez con solo obtener imágenes en la caché. Yendo y viniendo y viendo fotos ya presentadas es algo más rápido pero generalmente muy lento. Parece que no hay nada almacenado en la memoria caché, cerrando la aplicación y reiniciándola, todo vuelve a ser lento.
El código HTML equivalente fluye rápidamente. Algo de lentitud la primera vez, pero luego todo es muy rápido.
¿Qué está pasando? ¿El elemento usa algún almacenamiento en caché? ¿La lista realiza alguna precarga de las imágenes que no se presentan actualmente? ¿Hay alguna forma de decirle que haga? ¿Es realmente que mi única solución es administrar yo mismo los objetos de mapa de bits, junto con el almacenamiento en caché y la lógica de captación previa? Si es así, ¿algún trabajo previo que pueda incorporar?
EDITAR (resumen):
- @ H.B. responder para desactivar la virtualización le dará el mejor resultado. Todo el cuadro de lista se representa tan pronto como se carga la ventana y no se vuelve a calcular la imagen.
- @El código de Phil funciona muy bien y mejora el rendimiento, especialmente al ir y venir.
- Sin ningún código adicional, WPF no almacenará en caché las imágenes entre la invocación. El caché WinINET es NO utilizado. Aunque la solicitud viene con instrucciones de caché en el encabezado HTTP, WPF no hace nada con eso.
Gracias H. B. +1 y aceptar. – Uri