Otimizando o desempenho: layout e design
O design do aplicativo WPF pode afetar seu desempenho criando sobrecarga desnecessária no cálculo do layout e na validação de referências de objeto. A construção de objetos, especialmente em tempo de execução, pode afetar as características de desempenho do seu aplicativo.
Este tópico fornece recomendações de desempenho nessas áreas.
Disposição
O termo "passe de layout" descreve o processo de medir e organizar os membros de uma coleção de filhos de um objeto derivado de Panele, em seguida, desenhá-los na tela. A passagem de layout é um processo matematicamente intensivo, quanto maior o número de filhos na coleção, maior o número de cálculos necessários. Por exemplo, cada vez que um objeto UIElement criança na coleção muda de posição, ele tem o potencial de disparar uma nova passagem pelo sistema de layout. Devido à relação estreita entre as características do objeto e o comportamento do layout, é importante entender o tipo de eventos que podem invocar o sistema de layout. Seu aplicativo terá um desempenho melhor reduzindo o máximo possível de invocações desnecessárias da passagem de layout.
O sistema de layout conclui duas passagens para cada membro filho em uma coleção: um passe de medida e uma passagem de organização. Cada objeto filho fornece sua própria implementação substituída dos métodos Measure e Arrange para fornecer seu próprio comportamento de layout específico. No seu layout mais simples, o layout é um sistema recursivo que leva a um elemento sendo dimensionado, posicionado e desenhado na tela.
Um objeto filho UIElement inicia o processo de layout medindo primeiro suas propriedades principais.
As propriedades FrameworkElement do objeto relacionadas ao tamanho, como Width, Heighte Margin, são avaliadas.
A lógica específica do Panelé aplicada, como a propriedade Dock do DockPanelou a propriedade Orientation do StackPanel.
O conteúdo é organizado ou posicionado após todos os objetos filho serem medidos.
A coleção de objetos filhos é desenhada na tela.
O processo de passagem de layout será invocado novamente se alguma das seguintes ações ocorrer:
Um objeto filho é adicionado à coleção.
Um LayoutTransform é aplicado ao objeto filho.
O método UpdateLayout é chamado para o objeto filho.
Quando ocorre uma alteração no valor de uma propriedade de dependência marcada com metadados que afetam as passagens de medida ou organização.
Usar o painel mais eficiente sempre que possível
A complexidade do processo de layout é diretamente baseada no comportamento de layout dos elementos derivados de Panelque você usa. Por exemplo, um controle Grid ou StackPanel fornece muito mais funcionalidade do que um controle Canvas. O preço desse aumento maior na funcionalidade é um aumento maior nos custos de desempenho. No entanto, se você não precisar da funcionalidade fornecida por um controle Grid, deverá usar as alternativas menos dispendiosas, como um Canvas ou um painel personalizado.
Para obter mais informações, consulte Visão geral dos Painéis.
Atualizar em vez de substituir um RenderTransform
Você pode atualizar um Transform em vez de substituí-lo como o valor de uma propriedade RenderTransform. Isso é particularmente verdadeiro em cenários que envolvem animação. Ao atualizar um Transformexistente, você evita iniciar um cálculo de layout desnecessário.
Construa sua Árvore Top-Down
Quando um nó é adicionado ou removido da árvore lógica, as invalidações de propriedade são geradas no pai do nó e em todos os seus filhos. Como resultado, um modelo de construção de cima para baixo deve sempre ser seguido para evitar o custo de invalidações desnecessárias em nós que já foram validados. A tabela a seguir mostra a diferença na velocidade de execução entre a construção de uma árvore de cima para baixo versus de baixo para cima, em que a árvore tem 150 níveis de profundidade com um único TextBlock e DockPanel em cada nível.
Ação | Construção da árvore (em ms) | Renderização – inclui a construção de árvore (em ms) |
---|---|---|
De baixo para cima | 366 | 454 |
De cima para baixo | 11 | 96 |
O exemplo de código a seguir demonstra como criar uma árvore de cima para baixo.
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
Para obter mais informações sobre a árvore lógica, consulte Trees in WPF.
Consulte também
- Otimizando o Desempenho do Aplicativo WPF
- planejamento de para de desempenho do aplicativo
- Aproveitando o potencial do hardware
- Gráficos e imagens 2D
- Comportamento do Objeto
- Recursos de Aplicação
- Texto
- Vinculação de Dados
- outras recomendações de desempenho
- Layout
.NET Desktop feedback