WPF 2019的性能提示

您是WPF開發人員嗎?您的WPF應用程序是否存在性能低下的區域,或者運行得不盡如人意?如果是這樣,我有15條提示可幫助您確定和提高WPF應用程序的性能。

儘管WPF已有十多年的歷史,並且在過去幾年中已經得到了很大的改進,但仍有幾個領域可能會出現性能不佳的情況。表現不佳的原因包括不良的編碼習慣,綁定斷開,佈局複雜,缺少UI虛擬化等等。幸運的是,只需進行一些計劃並對WPF平臺有紮實的瞭解,您就可以讓WPF應用程序以驚人的速度躍升,並以毫秒爲單位跨越整個宇宙。

我整理了這15條提示,以幫助您提高WPF應用程序的性能。

1.簡化視覺樹

性能問題的常見根源是深度和複雜的佈局。使您的XAML標記替換簡單和淺。當在屏幕上放置UI元素時,每個元素都會觸發“佈局遍歷”(佈局遍歷和佈置遍歷) 。佈局遍歷是一個數學密集型過程-元素中的子代數越多,所需的計算數就越多。

2.虛擬化ItemsControls

如前所述,複雜而深入的可視化樹會導致更大的內存佔用空間和更慢的性能。ItemsControls通常會增加深層視覺樹的性能問題,因爲它們沒有被虛擬化。這意味着將不斷爲控件中的每個項目創建和銷燬它們。而是使用VirtualizingStackPanel作爲項目宿主,並使用VirtualizingStackPanel.IsVirtualizing並將VirtualizationMode設置爲Recycling,以便重新使用項目容器,而不是每次都創建新的容器。

3.偏愛StaticResources而不是DynamicResources

StaticResources通過查找對已定義資源的引用來爲任何XAML屬性屬性提供值。該資源的查找行爲與編譯時查找相同。DynamicResources 將創建一個臨時表達式並添加對資源的查找,直到需要所請求的資源值爲止。該資源的查找行爲與運行時查找相同,這會對性能造成影響。始終正確使用StaticResource。

4.畫筆上的不透明度而不是元素

如果使用“畫筆”設置元素的“填充”或“描邊”,則最好在“畫筆”上設置“不對齊”,而不是設置元素的“不透明度”屬性。修改元素的“不透明度”屬性時,它可能導致WPF創建臨時曲面,從而導致性能下降。

5.避免使用運行來設置文本屬性

避免在TextBlock中使用Runs,因爲這會導致更高的性能密集型操作。如果使用“運行”來設置文本屬性,請直接在TextBlock上進行設置。

6.偏愛StreamGeometries而不是PathGeometries

StreamGeometry 經過優化,可以處理許多PathGeometry對象。與使用許多PathGeometry對象,它消耗了很多內存,並且性能更好。

7.使用縮小的圖像尺寸

如果您的應用程序需要顯示較小的尺寸,請考慮創建縮小尺寸的圖像。替換情況下,WPF將加載並解碼圖像到其完整尺寸。如果要加載完整的圖像尺寸爲其縮小爲ItemControl等控件中的尺寸大小,這可能是許多性能問題的根源。如果可能,將所有圖像組合成一個圖像,例如由多個圖像組成的膠片。

8.降低BitMapScalingMode

默認情況下,WPF使用縮放的圖像重採樣算法,該算法有時會消耗系統資源,這會導致幀速率下降並導致動畫停頓。否則將BitMapScalingMode設置爲低質量,以從“質量優化”算法切換爲“速度優化”算法。

9.使用和凍結

Freezable是一種特殊的對象類型,具有兩種狀態:未凍結和已凍結。凍結筆刷或幾何圖形等對象時,將無法再對其進行修改。儘可能凍結對象可以提高應用程序的性能並減少其內存消耗。

10.修正您的裝訂錯誤

綁定錯誤是WPF應用程序中最常見的性能問題。每次發生綁定錯誤時,您的應用都會受到性能影響,並嘗試解析綁定並將錯誤寫到跟蹤日誌中。可以想象,綁定錯誤越多,應用程序獲得的性能就會越高。花點時間查找並修復所有綁定錯誤。在DataTemplates中使用RelativeSource綁定是綁定錯誤的主要根源,因爲通常在DataTempate完成其初始化之前,綁定才能正確解析。避免不惜一切代價使用RelativeSource.FindAncestor。而是定義一個附加屬性,並使用屬性繼承將值推入可視樹,而不是查找可視樹。

11.避免數據綁定到Label.Content屬性

如果使用標籤將數據綁定到String屬性,這將導致性能下降。這是因爲每次更新String源時,都會丟棄舊的字符串對象,並創建一個新的String。如果Label的內容是簡單文本,則將其替換爲TextBlock,然後綁定到Text屬性。

12.將ItemsControls綁定到IList而不是IEnumerable

當將ItemsControl綁定到IEnumerable的數據時,WPF將創建類型爲IList <T>的包裝,這會對創建第二個對象產生負面影響。而是,將ItemsControl直接綁定到IList,以避免包裝對象的開銷。

13.使用NeutralResourcesLanguage屬性

使用NeutralResourcesLanguageAttribute告訴ResourceManager什麼是中性區域性,並避免不成功的附屬程序集查找。

14.在單獨的線程上加載數據

性能問題,UI凍結以及停止響應的應用程序的一個非常常見的來源是如何加載數據。確保您在單獨的線程上異步加載數據,以免UI線程超載。在UI線程上加載數據將導致非常差的性能以及最終用戶的整體體驗。每個WPF開發人員都應在其應用程序中使用多線程。

15.當心內存泄漏

在大多數WPF應用程序中,內存泄漏是導致性能問題的首要原因。它們很容易擁有,但很難找到。例如,使用DependencyPropertyDescriptor.AddValueChanged可以使WPF框架強烈引用事件源,除非您手動調用DependencyPropertyDescriptor.RemoveValueChanged ,否則該事件源不會刪除。如果您的視圖或行爲依賴於從對象或ViewModel引發的事件(例如INotifyPropertyChanged),請進行進行弱訂閱或確保您手動取消訂閱。INotifyPropertyChanged的ViewModel中的屬性,則很可能發生內存泄漏。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章