考慮以下示例XAML文件,其中顯示Facebook的前1000人,以markz作爲第4人開始。請注意,這只是一個示例。任何有1000個元素的窗口,無論你如何構建它,都是一個很好的示範。爲什麼<Image Source ='...'>這麼慢,我能做些什麼呢?
<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>
而後面的代碼:
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;
}
}
在一個非常合理的臺式機和高速連接,程序是極其緩慢。試圖用ScrollBar滾動...說到中間,將需要30秒。點擊「主頁」和「結束」鍵將花費大量時間。
這不是第一次得到圖像到緩存問題。來回看看已經呈現的圖片比較快,但通常非常慢。看起來沒有任何東西存儲在緩存中,關閉應用程序並重新啓動它,一切都很慢。
等效的HTML代碼快速流血。第一次有些緩慢,但一切都很快。
這是怎麼回事?元素是否使用任何緩存?該列表是否對當前未呈現的圖像進行預取?無論如何要告訴它做?我真的唯一的解決方案是自己管理Bitmap對象,還有緩存和預取邏輯?如果是這樣,以前的任何工作我可以合併?
EDIT(摘要):
- @ H.B。答案關閉虛擬化會給你最好的結果。整個列表框會在窗口加載後立即生成,並且不會重新計算圖像
- @Pil代碼效果很好,它可以提高性能,特別是在來回時。
- 沒有任何額外的代碼,WPF不會在調用之間緩存圖像。 WinINET緩存使用的是而不是。儘管請求在HTTP Header中帶有Cache指令,但WPF並沒有執行任何操作。
謝謝H.B. +1並接受。 – Uri 2012-02-26 06:52:28