WPF程序性能


WPF程序性能由很多因素造成,以下是簡單地總結:

元素:

1、  減少需要顯示的元素數量:去除不需要或者冗余的XAML元素代碼. 通過移出不必要的元素,合並layout panels,簡化templates來減少可視化樹的層次。這可以保證第內存使用,而改變渲染性能。

2、  UI虛擬化:只顯示當前需要顯示的元素.

3、  不要把不要顯示的自定義控件隱藏在主界面中:雖然它們不會顯示出來,但是程序啟動時還是會去計算自定義控件所需的空間和位置. 

4、  VirtualizingStackPanel對Item類型控件重寫時,使用VirtualizingStackPanel作為ItemPanel,這樣列表資源可以只渲染當前需要的內容。不過如果設置CanContextScrol="True"會阻止虛擬化,另外使用VirtualizingStackPanel時,可以設置VirtualizingStackPanel.VirtualizationMode="Recycling", 這樣已經顯示過的列表不會被重復創建和釋放掉。

5、  凍結可以凍結的控件:通過在代碼中調用Freeze()或者在Xmal中設定PresentationOptions:Freeze="true"來凍結可以凍結的控件。由於這樣系統不必監聽該控件的變化,所以可以帶來性能的提升.

6、  盡可能使用StreamGeometries 代替PathGeometries:因為它可以一低內存占用,更高效.

7、  盡量多使用Canvas等簡單的布局元素:少使用Grid或者StackPanel等復雜的,越復雜性能開銷越大

8、  盡量不要使用ScrollBarVisibility=Auto

9、  如果需要修改元素的Opacity屬性,最后修改一個Brush的屬性,然后用這個Brush來填充元素。因為直接修改元素的Opacity會迫使系統創建一個臨時的Surface

10、 使用延遲滾動增強用戶體驗:如果你還記得可滾動的DataGrid或ListBox,它們往往會降低整個應用程序的性能,因為在滾動時會強制連續更新,這是默認的行為,在這種情況下,我們可以使用控件的延遲滾動(Deferred Scrolling)屬性增強用戶體驗。你需要做的僅僅是將IsDeferredScrollingEnabled附加屬性設為True

11、 使用容器回收提高性能: 你可以通過回收執行虛擬化的容器來提高性能,下面的代碼片段將ViruatlizationMode設為Recycling,它讓你可以獲得更好的性能。當用戶滾動或抵達另一個項目時,它強制重復使用容器對象。

線程:

1、  耗時操作放在放在非UI線程上處理,保持UI的順暢:處理完成后如果需要在UI上展示,調用Dispatcher.BeginInoke()方法

綁定:

1、  Mode關於Data Binding,根據實際情況對Binding指定不同的Mode,性能比較:OneTime>OneWay>TwoWay。

2、  修正系統中Binding錯誤:在Visual Studio的輸出日志中查找System.Windows.Data Error。

3、  在使用數據綁定的過程中,如果綁定的數據源是一個CLR對象,屬性也是一個CLR屬性,那么在綁定的時候對象CLR對象所實現的機制不同,綁定的效率也不同。

4、  訪問CLR對象和CLR屬性的效率會比訪問DependencyObject/DependencyProperty高。注意這里指的是訪問,不要和前面的綁定混淆了。但是,把屬性注冊為DependencyProperty會有很多的優點:比如繼承、數據綁定和Style。

5、  數據源是一個CLR對象,屬性也是一個CLR屬性。對象通過TypeDescriptor/PropertyChanged模式實現通知功能。此時綁定引擎用TypeDescriptor來反射源對象。效率最低。

6、  數據源是一個CLR對象,屬性也是一個CLR屬性。對象通過INotifyPropertyChanged實現通知功能。此時綁定引擎直接反射源對象。效率稍微提高。

7、  數據源是一個DependencyObject,而且屬性是一個DependencyProperty。此時不需要反射,直接綁定。效率最高。

8、  當一個CLR對象很大時,比如有1000個屬性時,盡量把這個對象分解成很多很小的CLR對象。比如分成1000個只有一個屬性的CLR對象。

9、  當我們在列表(比如ListBox)顯示了一個CLR對象列表(比如List)時,如果想在修改List對象后,ListBox也動態的反映這種變化。此時,我們應該使用動態的ObservableCollection對象綁定。而不是直接的更新ItemSource。兩者的區別在於直接更新ItemSource會使WPF拋棄ListBox已有的所有數據,然后全部重新從List加載。而使用ObservableCollection可以避免這種先全部刪除再重載的過程,效率更高。

10、       盡量綁定IList而不是IEnumerable到ItemsControl。

資源:

1、  通常情況下我們會把樣式資源都統一到App.xaml中,這是很好的,便於資源的管理。

2、  盡量把多次重復用到的資源放到App.xaml中。例如某些頁面的資源只會在當前頁面中使用到,那么可以把資源定義在當前頁面; 因為放在控件中會使每個實例都保留一份資源的拷貝。

3、  如非必要,不要使用DynaicResource,使用StaticResource即可;

動畫:

1、  盡量少的使用Animation:程序啟動時,Animation渲染時會占用一些CPU資源。

2、  降低動畫的幀率:大多數動畫不需要高幀率,而系統默認為60frames/sec,所以可以設定Storyboard.DesiredFrameRate 為更低值。

3、  使用卸載事件卸載不必要的動畫:動畫肯定會占用一定的資源,如果處置方式不當,將會消耗更多的資源,如果你認為它們無用時,你應該考慮如何處理他們,如果不這樣做,就要等到可愛的垃圾回收器先生來回收資源。

4、   

圖像:

1、   對Image做動畫處理的時候(如調整大小等),可以使用這條語句RenderOptions.SetBitmapScalingMode(MyImage,BitmapScalingMode.LowQuality),以改善性能。

2、   用TileBrush的時候,可以CachingHint。

3、  預測圖像繪制能力:根據硬件配置的不同,WPF采用不同的Rendering Tier做渲染。下列情況請特別注意,因為在這些情況下,即使是處於Rendering Tier 2的情況下也不會硬件加速。(不全,其余請查閱SDK)

文本:

1、  文字少的時候用TextBlock或者label,長的時候用FlowDocument.

2、  使用元素TextFlow和TextBlock時,如果不需要TextFlow的某些特性,就應該考慮使用TextBlock,因為它的效率更高。

3、  在TextFlow中使用UIElement(比如TextBlock)所需的代價要比使用TextElement(比如Run)的代價高.在FlowDocument中盡量避免使用TextBlock,要用Run替代。

4、  在TextBlock中顯式的使用Run命令比不使用Run命名的代價要高。

5、  把Label(標簽)元素的ContentProperty和一個字符串(String)綁定的效率要比把字符串和TextBlock的Text屬性綁定的效率低。因為Label在更新字符串是會丟棄原來的字符串,全部重新顯示內容。如果字符串不需要更新,用Label就無所謂性能問題。

6、  在TextBlock塊使用HyperLinks時,把多個HyperLinks組合在一起效率會更高。

7、  顯示超鏈接的時候,盡量只在IsMouseOver為True的時候顯示下划線,一直顯示下划線的代碼高很多

8、  盡量不使用不必要的字符串連接

9、  使用字體緩存服務提高啟動時間:WPF應用程序之間可以共享字體數據,它是通過一個叫做PresentationFontCache Service的Windows服務實現的,它會隨Windows自動啟動。你可以在控制面板的“服務”中找到這個服務(或在“運行”框中輸入Services.msc),確保這個服務已經啟動。

其他:

1、  用NavigationWindow的時候,盡量Update the client area by object,而不是URI

2、  建立邏輯樹或者視覺樹的時候,遵循Top-Down的原則

3、  使用WPF分析工具分析WPF程序:分析WPF程序是理解其行為很重要的一步,市場上有大量現成的WPF程序分析工具,如Snoop,WPFPerf,Perforator和Visual Profiler,其中Perforator和Visual Profiler是WPF Performance Suite的一部分,要了解這些工具的用法,請去它們的項目主頁。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM