最佳化效能:配置與設計
WPF 應用程式的設計可能會因為在計算版面配置和驗證物件參考而產生不必要的額外負荷,進而影響其效能。 物件的建構,特別是在執行階段,可能會影響應用程式的效能特性。
本主題提供這些區域的效能建議。
版面配置
「版面配置傳遞」一詞描述測量和安排 Panel 衍生物件的子系集合成員,並在螢幕上繪製它們的程序。 配置傳遞是數學密集的程序,在集合中的子系數目愈大,需要的計算數目愈大。 例如,每次集合中的子系 UIElement 物件變更位置時,就有可能觸發版面配置系統的新階段。 由於物件特性與版面配置行為之間的密切關係,了解可以叫用版面配置系統的事件類型便很重要。 藉由盡可能減少版面配置傳遞中任何不必要的引動過程,您的應用程式效能會比較好。
版面配置系統會為集合中每個子成員完成兩個階段︰測量階段和排列階段。 每個物件都會提供自己覆寫的 Measure 和 Arrange 方法實作,以提供自己的特定版面配置行為。 簡單來說,版面配置是導致項目調整大小、定位並在螢幕上繪製的遞迴系統。
子 UIElement 物件的版面配置流程一開始會先測量其核心屬性。
評估物件與其大小相關的 FrameworkElement 屬性,例如 Width、 Height和 Margin。
會套用 Panel 特定邏輯,例如 DockPanel 的 Dock屬性,或 StackPanel 的 Orientation屬性。
在測量所有子物件之後,會排列 (或定位) 內容。
子物件的集合會繪製到螢幕。
如果發生任何下列動作,會再次叫用配置傳遞流程︰
子物件新增至集合。
LayoutTransform 會套用至子物件。
子物件會呼叫 UpdateLayout 方法。
當發生在以中繼資料標示的相依性屬性值的變更會影響測量或排列階段時。
請盡可能使用最有效率的面板
版面配置流程的複雜性是直接根據您使用的 Panel 衍生項目的版面配置行為。 例如,Grid 或 StackPanel 控制項提供的功能遠高於 Canvas 控制項。 這種功能增加的代價是較高的效能成本。 不過,如果您不需要 Grid 控制項提供的功能,您應該使用成本更低的替代項目,例如 Canvas 或自訂的面板。
如需詳細資訊,請參閱面板概觀。
更新,而不是取代 RenderTransform
您可以更新 Transform ,而不是將它取代為 RenderTransform 屬性的值。 特別是在包含動畫的案例。 藉由更新現有的 Transform,您可避免起始不必要的配置計算。
由上而下建置您的樹狀結構
在邏輯樹狀結構節點新增或移除節點時,會對節點之父代及其所有子系引發屬性失效。 因此,應該一律遵循由上而下的建構模式,以避免在已驗證的節點上發生不必要的失效成本。 下表顯示在由上而下和由下而上建立樹狀結構時,兩者之間的執行速度差異,其中樹狀結構有 150 層深,且在每個層級有單一的 TextBlock 和 DockPanel。
動作 | 樹狀結構建置 (毫秒) | 轉譯 — 包括樹狀結構建置 (毫秒) |
---|---|---|
由下而上 | 366 | 454 |
由上而下 | 11 | 96 |
下列程式碼範例示範如何由上而下建立樹狀結構。
private void OnBuildTreeTopDown(object sender, RoutedEventArgs e)
{
TextBlock textBlock = new TextBlock();
textBlock.Text = "Default";
DockPanel parentPanel = new DockPanel();
DockPanel childPanel;
myCanvas.Children.Add(parentPanel);
myCanvas.Children.Add(textBlock);
for (int i = 0; i < 150; i++)
{
textBlock = new TextBlock();
textBlock.Text = "Default";
parentPanel.Children.Add(textBlock);
childPanel = new DockPanel();
parentPanel.Children.Add(childPanel);
parentPanel = childPanel;
}
}
Private Sub OnBuildTreeTopDown(ByVal sender As Object, ByVal e As RoutedEventArgs)
Dim textBlock As New TextBlock()
textBlock.Text = "Default"
Dim parentPanel As New DockPanel()
Dim childPanel As DockPanel
myCanvas.Children.Add(parentPanel)
myCanvas.Children.Add(textBlock)
For i As Integer = 0 To 149
textBlock = New TextBlock()
textBlock.Text = "Default"
parentPanel.Children.Add(textBlock)
childPanel = New DockPanel()
parentPanel.Children.Add(childPanel)
parentPanel = childPanel
Next i
End Sub
如需邏輯樹狀結構的詳細資訊,請參閱 WPF 中的樹狀結構。