語言

最佳化效能:配置與設計

WPF 應用程式的設計可能會因為在計算版面配置和驗證物件參考而產生不必要的額外負荷,進而影響其效能。 物件的建構,特別是在執行階段,可能會影響應用程式的效能特性。

本主題提供這些區域的效能建議。

版面配置

「版面配置階段」一詞描述測量和排列 Panel 衍生物件的子系集合成員,然後在螢幕上繪製它們的過程。 配置遍歷是一個數學計算密集的過程,集合中的子元素數量愈多,需要進行的計算也愈多。 例如,每次集合中的子物件 UIElement 變更位置時,就有可能觸發版面配置系統的新階段。 由於物件特性與版面配置行為之間的密切關係,了解可以叫用版面配置系統的事件類型便很重要。 藉由盡可能減少版面配置階段中任何不必要的調用,您的應用程式效能會改善。

版面配置系統會為集合中每個子成員完成兩個階段︰測量階段和排列階段。 每個子物件都會提供自己覆寫的 Measure 和 Arrange 方法的實作,以提供自己的特定版面配置行為。 簡單來說,版面配置是導致項目調整大小、定位並在螢幕上繪製的遞迴系統。

  • 子 UIElement 物件開始進行版面配置流程時,會先測量其核心屬性。

  • 物件的與大小相關的屬性,例如 FrameworkElement、Width 和 Height,會被評估。

  • 會套用 Panel 專屬邏輯,例如 Dock 的 DockPanel 屬性,或 Orientation 的 StackPanel 屬性。

  • 在測量完所有子物件後,會排列或設定內容的位置。

  • 子物件的集合會顯示在螢幕上。

如果發生任何下列動作,會再次叫用配置傳遞流程︰

  • 子物件被添加至集合。

  • 子物件被應用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 中的樹狀結構。

另請參閱