15 dicas de desempenho do WPF
Você é um desenvolvedor do WPF? Aqui apresentamos 15 dicas para ajudá-lo a identificar e melhorar o desempenho de seus aplicativos WPF. Leia mais.
Você é um desenvolvedor do WPF? Seus aplicativos WPF têm áreas de baixo desempenho ou não são executados tão rapidamente quanto você gostaria? Nesse caso, tenho 15 dicas para ajudá-lo a identificar e melhorar o desempenho de seus aplicativos WPF.
Embora o WPF tenha mais de uma década e tenha sido muito aprimorado ao longo dos anos, ainda existem várias áreas que podem sofrer com o baixo desempenho. As razões para esse baixo desempenho incluem coisas como práticas de codificação ruins, associações quebradas, layouts complexos, falta de virtualização da interface do usuário e muito mais. Felizmente, com um pouco de planejamento e uma sólida compreensão da plataforma WPF, você pode fazer com que seus aplicativos WPF entrem em alta velocidade e saltem pelo universo em milissegundos.
Reuni essas 15 dicas para ajudá-lo a melhorar o desempenho de seus aplicativos WPF.
1. Simplifique sua árvore visual
Uma fonte comum de problemas de desempenho é um layout profundo e complexo. Mantenha sua marcação XAML o mais simples e superficial possível.Quando os elementos da interface do usuário são desenhados na tela, uma "passagem de layout" é chamada duas vezes para cada elemento (uma passagem de medida e uma passagem de organização). Apassagem de layout é um processo matematicamente intensivo - quanto maior o número defilhosnoelemento, maior o número de cálculos necessários.
2. Virtualize seus ItemsControls
Como mencionado anteriormente, uma árvore visual complexa e profunda resulta em um maior volume de memória e desempenho mais lento. ItemsControls geralmente aumentam os problemas de desempenho com árvores visuais profundas porque não são virtualizadas. Isso significa que eles estão constantemente sendo criados e destruídos para cada item no controle. Em vez disso, use o VirtualizingStackPanel como o host de itens e use o VirtualizingStackPanel.IsVirtualizing e defina o VirtualizationMode como Recycling para reutilizar contêineres de itens em vez de criar novos a cada vez.
3. Favoreça StaticResources em vez de DynamicResources
StaticResources fornece valores para qualquer atributo de propriedade XAML pesquisando uma referência a um recurso já definido. O comportamento de pesquisa para esse recurso é o mesmo que uma pesquisa em tempo de compilação. DynamicResources criará uma expressão temporária e adiará a pesquisa de recursos até que o valor do recurso solicitado seja necessário. O comportamento de pesquisa para esse recurso é o mesmo que uma pesquisa em tempo de execução, que impõe um impacto no desempenho. Sempre use um StaticResource sempre que possível.
4. Opacidade em pincéis em vez de elementos
Se você usar um Brush para definir o Fill ou o Stroke de um elemento, é melhor definir a Opacity no Brush em vez de definir a propriedade Opacity do elemento. Quando você modifica a propriedade Opacity de um elemento, isso pode fazer com que o WPF crie superfícies temporárias, o que resulta em um impacto no desempenho.
5. Avoid Using Run to Set Text Properties
Evite usar Runs em um TextBlock, pois isso resulta em uma operação intensiva de desempenho muito maior. Se você estiver usando um Run para definir propriedades de texto, defina-as diretamente no TextBlock.
6. Favor StreamGeometries over PathGeometries
O objeto StreamGeometry é uma alternativa muito leve a um PathGeometry. StreamGeometry é otimizado para lidar com muitos objetos PathGeometry. Ele consome menos memória e tem um desempenho muito melhor quando comparado ao uso de muitos objetos PathGeometry.
7. Use Reduced Image Sizes
Se o aplicativo exigir a exibição de miniaturas menores, considere criar versões de tamanho reduzido de suas imagens. Por padrão, o WPF carregará e decodificará sua imagem para seu tamanho real. Isso pode ser a origem de muitos problemas de desempenho se você estiver carregando imagens completas e dimensionando-as para tamanhos de miniatura em controles como um ItemsControl. Se possível, combine todas as imagens em uma única imagem, como uma tira de filme composta por várias imagens.
8. Lower the BitMapScalingMode
Por padrão, o WPF usa um algoritmo de reamostragem de imagem de alta qualidade que às vezes pode consumir recursos do sistema, o que resulta na degradação da taxa de quadros e faz com que as animações gaguejem. Em vez disso, defina o BitMapScalingMode como LowQuality para alternar de um algoritmo "otimizado para qualidade" para um algoritmo "otimizado para velocidade".
9. Use e congele Freezables
Um Freezable é um tipo especial de objeto que tem dois estados: descongelado e congelado. Quando você congela um objeto, como um Pincel ou Geometria, ele não pode mais ser modificado. Congelar objetos sempre que possível melhora o desempenho do aplicativo e reduz o consumo de memória.
10. Fix your Binding Errors
Erros de associação são o tipo mais comum de problema de desempenho em aplicativos WPF. Sempre que ocorre um erro de associação, seu aplicativo recebe um acerto de desempenho e, ao tentar resolver a associação, grava o erro no log de rastreamento. Como você pode imaginar, quanto mais erros de vinculação você tiver, maior será o impacto no desempenho do seu aplicativo. Reserve um tempo para encontrar e corrigir todos os seus erros de vinculação. O uso de uma associação RelativeSource em DataTemplates é um dos principais culpados pelo erro de associação, pois a associação geralmente não é resolvida corretamente até que o DataTempate tenha concluído sua inicialização. Evite usar RelativeSource.FindAncestor a todo custo. Em vez disso, defina uma propriedade anexada e use a herança de propriedade para enviar valores para baixo na árvore visual em vez de pesquisar a árvore visual.
11. Evite a vinculação de dados à propriedade Label.Content
Se você estiver usando um Label para associação de dados a uma propriedade String, isso resultará em um desempenho ruim. Isso ocorre porque cada vez que a origem String é atualizada, o objeto string antigo é descartado e um novo String é criado. Se o conteúdo do rótulo for texto simples, substitua-o por um TextBlock e associe-o à propriedade Text.
12. Bind ItemsControls to IList instead of IEnumerable
Ao vincular dados a um ItemsControl a um IEnumerable, o WPF criará um wrapper do tipo IList<T> que afeta negativamente o desempenho com a criação de um segundo objeto. Em vez disso, associe o ItemsControl diretamente a um IList para evitar a sobrecarga do objeto wrapper.
13. Use the NeutralResourcesLanguage Attribute
Use o NeutralResourcesLanguageAttribute para informar ao ResourceManager qual é a cultura neutra e evitar pesquisas de assembly satélite malsucedidas.
14. Carregar dados em threads separados
Uma fonte muito comum de problemas de desempenho, congelamentos de interface do usuário e aplicativos que param de responder é como você carrega seus dados. Verifique se você está carregando seus dados de forma assíncrona em um thread separado para não sobrecarregar o thread da interface do usuário. Carregar dados no thread da interface do usuário resultará em um desempenho muito ruim e uma experiência geral ruim para o usuário final. Multi-threading deve ser algo que todo desenvolvedor do WPF está usando em seus aplicativos.
15. Beware of Memory Leaks
Vazamentos de memória são a causa número um de problemas de desempenho na maioria dos aplicativos WPF. Eles são fáceis de ter, mas podem ser difíceis de encontrar. Por exemplo, usar o DependencyPropertyDescriptor.AddValueChanged pode fazer com que a estrutura do WPF faça uma referência forte à origem do evento que não é removida até que você chame manualmente DependencyPropertyDescriptor.RemoveValueChanged. Se suas exibições ou comportamentos dependerem de eventos gerados de um objeto ou ViewModel (como INotifyPropertyChanged), assine-os fracamente ou verifique se você está cancelando a assinatura manualmente. Além disso, se você estiver associando a propriedades em um ViewModel que não implementa INotifyPropertyChanged, é provável que você tenha um vazamento de memória.
Finalmente, uma dica bônus. Às vezes, quando você tem um problema de desempenho, pode ser muito difícil identificar o que exatamente está causando o problema. Sugiro usar um criador de perfil de desempenho de aplicativo para ajudar a identificar onde esses gargalos de desempenho estão ocorrendo em sua base de código. Existem muitas opções de criadores de perfil disponíveis para você. Alguns são pagos e outros são gratuitos. O que eu pessoalmente mais uso são as Ferramentas de Diagnóstico incorporadas diretamente ao Visual Studio 2019.
Certifique-se de interagir comigo no Twitter, inscreva-se no meu canal do YouTube para ser notificado sobre novos conteúdos de vídeo e siga-me no Twitch para me ver transmitir ao vivo. E se você estiver usando Ultimate UI for WPF, certifique-se de se conectar com nossas várias equipes por meio de nossos Fóruns da Comunidade, onde você pode interagir com engenheiros Infragistics e outros clientes.