Otimizando o desempenho: Layout and Design
O design da sua aplicação WPF pode impactar seu desempenho criando overhead desnecessário para calcular o layout e validar referências de objetos. A construção de objetos, em particular em tempo de execução, pode afetar as características de desempenho de sua aplicação.
Esse tópico oferece recomendações de desempenho nessas áreas.
Layout
O termo "varredura de layout" ("layout pass") descreve o processo de medir e organizar os membros de uma coleção de filhos de objetos derivados de Panel e então desenhá-los na tela. A varredura de layout é um processo matematicamente intensivo -- quanto maior o número de filhos da coleção, maior o número de cálculos necessários. Por exemplo, cada vez que um objeto filho UIElement da coleção muda sua posição, tem o potencial de disparar uma nova varredura pelo sistema de layout. Por causa do relacionamento próximo entre as características de um objeto e comportamento de layout, é importante entender os tipos de eventos que podem invocar o sistema de layout. Sua aplicação vai ter um desempenho melhor reduzindo tanto quanto possível invocações desnecessárias da varredura de layout.
O sistema de layout passa dois para cada membro filho em uma coleção: uma passagem de medida e passar uma organização. Cada objeto filho oferece sua própria implementação sobrecarregada dos métodos Measure e Arrange para oferecer seu próprio comportamento específico de layout. Na sua forma mais simples, layout é um sistema recursivo que faz com que um elemento seja dimensionado, posicionado e desenhado na tela.
Um objeto filho UIElement começa o processo de layout tendo suas propriedades básicas medidas.
As propriedades FrameworkElement do objeto que estão relacionadas a tamanho, tais como Width, Height e Margin, são avaliadas.
Lógica específica de Panel é aplicada, tal como a propriedade Dock do DockPanel ou a propriedade Orientation do StackPanel.
O conteúdo é organizado, ou posicionado, após todos os objetos-filho terem sido medidos.
A coleção de objetos filho é desenhada na tela.
O processo de varredura de layout é invocado novamente se qualquer uma das seguintes ações ocorrer:
Um objeto filho é acrescentado à coleção.
Uma LayoutTransform é aplicada ao objeto filho.
O método UpdateLayout é chamado para o objeto filho.
Quando uma mudança ocorre no valor de uma propriedade de dependência que esteja marcada com metadados afetando as verreduras de medida ou organização.
Utilize o Painel Mais Eficiente onde Possivel
A complexidade do processo de layout é baseada diretamente no comportamento de layoute dos elementos derivados de Panel que você utiliza. Por exemplo, um controle Grid ou StackPanel oferece muito mais funcionalidade do que um controle Canvas. O preço para esse aumento de funcionalidade é um aumento maior em custo de desempenho. Entretanto, se você não requer a funcionalidade que um controle Grid oferece, você deve utilizar as alternativas menos custosas, comoo Canvas ou um painel personalizado.
Para obter mais informações, consulte Panels Overview.
Atualizar em vez de Substituir uma Transformação de Renderização
Você pode ser capaz de atualizar uma Transform em vez de substituí-la como o valor de uma propriedade RenderTransform. Isso é verdade em particular em cenários que envolvem animação. Ao atualizar um Transform existente, você evita iniciar um cálculo de layout desnecessário.
Construa sua Própria Árvore Top-Down
Quando um nó é acrescentado ou removido da árvore lógica, invalidações de propriedade são disparadas no pai do nó e em todos seus filhos. Como resultado, um padrão de construção top-down 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 em tempo de execução entre construir uma árvore top-down versus bottom-up, onde 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 construção da árvore (em ms) |
---|---|---|
Bottom-up |
366 |
454 |
Top-down |
11 |
96 |
O seguinte exemplo de código demonstra como criar uma árvore top down.
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;
}
}
Para mais informações sobre a árvore lógica, veja Árvores em WPF.
Consulte também
Conceitos
Optimizing WPF Application Performance
Planejando para desempenho de aplicativos
Otimizando o desempenho: Levando vantagens de hardware
Otimizando o desempenho: 2D Graphics and Imaging
Otimizando o desempenho: Comportamento de objeto
Otimizando o desempenho: Recursos do aplicativo
Otimizando o desempenho: Texto
Otimizando o desempenho: Ligação de Dados
Otimizando o desempenho: Outras recomendações