Optimizing Performance: Layout and Design
The design of your WPF application can impact its performance by creating unnecessary overhead in calculating layout and validating object references. The construction of objects, particularly at run time, can affect the performance characteristics of your application.
This topic provides performance recommendations in these areas.
The term "layout pass" describes the process of measuring and arranging the members of a Panel-derived object's collection of children, and then drawing them onscreen. The layout pass is a mathematically-intensive process—the larger the number of children in the collection, the greater the number of calculations required. For example, each time a child UIElement object in the collection changes its position, it has the potential to trigger a new pass by the layout system. Because of the close relationship between object characteristics and layout behavior, it's important to understand the type of events that can invoke the layout system. Your application will perform better by reducing as much as possible any unnecessary invocations of the layout pass.
The layout system completes two passes for each child member in a collection: a measure pass, and an arrange pass. Each child object provides its own overridden implementation of the Measure and Arrange methods in order to provide its own specific layout behavior. At its simplest, layout is a recursive system that leads to an element being sized, positioned, and drawn onscreen.
A child UIElement object begins the layout process by first having its core properties measured.
Content is arranged, or positioned, after all child objects have been measured.
The collection of child objects is drawn to the screen.
The layout pass process is invoked again if any of the following actions occur:
The complexity of the layout process is directly based on the layout behavior of the Panel-derived elements you use. For example, a Grid or StackPanel control provides much more functionality than a Canvas control. The price for this greater increase in functionality is a greater increase in performance costs. However, if you do not require the functionality that a Grid control provides, you should use the less costly alternatives, such as a Canvas or a custom panel.
For more information, see Panels Overview.
When a node is added or removed from the logical tree, property invalidations are raised on the node's parent and all its children. As a result, a top-down construction pattern should always be followed to avoid the cost of unnecessary invalidations on nodes that have already been validated. The following table shows the difference in execution speed between building a tree top-down versus bottom-up, where the tree is 150 levels deep with a single TextBlock and DockPanel at each level.
Tree building (in ms)
Render—includes tree building (in ms)
The following code example demonstrates how to create a tree top down.
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
For more information on the logical tree, see Trees in WPF.
Optimizing WPF Application Performance
Planning for Application Performance
Optimizing Performance: Taking Advantage of Hardware
Optimizing Performance: 2D Graphics and Imaging
Optimizing Performance: Object Behavior
Optimizing Performance: Application Resources
Optimizing Performance: Text
Optimizing Performance: Data Binding
Optimizing Performance: Other Recommendations