Nuestro equipo se enfrentó a problemas de rendimiento de representación . En nuestro caso, tenemos alrededor de 400 unidades de transporte y deberíamos representar el gráfico de cada unidad con muchos detalles (etiquetas de texto, marcas especiales, geometrías diferentes, etc.).
En la primera de nuestras implementaciones, dividimos cada gráfico en primitivas y compusimos el gráfico de unidades enteras a través de Enlace. Fue muy triste expirience. La reacción de UI fue extremadamente lenta.
Así que decidimos crear un elemento de interfaz de usuario por cada unidad y renderizar el gráfico con DrawingContext. Aunque esto fue mucho mejor en el aspecto de rendimiento, pasamos cerca de un mes mejorando la representación.
algunos consejos:
- caché todo. Pinceles, colores, geometrías, textos formateados, glifos. (Por ejemplo, tenemos dos clases:
RenderTools
y TextCache
. Proceso de representación de direcciones de cada unidad a instancia compartida de ambas clases. Por lo tanto, si dos gráficos tienen el mismo texto, su preparación se ejecuta una sola vez)
- Congelar
Freezable
, si planean usarlo por un largo tiempo. Especialmente geometrías. Las geometrías complejas sin congelar ejecutan HitTest extremadamente lento.
- Elija las formas más rápidas de representación de cada primitiva. Por ejemplo, hay aproximadamente 6 formas de representación de texto, pero la más rápida es
DrawingContext.DrawGlyphs
.
- Utilice el generador de perfiles para descubrir los puntos calientes. Por ejemplo, en nuestro proyecto teníamos la memoria caché de geometrías y la aprobamos a demanda. Parecía que no hay mejoras posibles. Pero un día pensamos qué pasaría si renderizamos las geometrías una vez y almacenamos imágenes visuales listas para caché. En nuestro caso, ese enfoque fue aceptable. El gráfico de nuestra unidad tiene solo varios estados. Cuando se cambian los datos del gráfico, reconstruimos DrawingVisual para cada estado y los ponemos en el caché.
Por supuesto, esta forma necesita algunas inversiones, es un trabajo aburrido y aburrido, pero el resultado es increíble.
Por cierto: cuando activamos la opción de almacenamiento en caché de WPF (puede encontrar un enlace en las respuestas), nuestra aplicación se colgó.
¿Puedes dar algunos números? Número de controles por ventana, etc. – NVM
@NVM Prácticamente, ahora se trata de unos mil controles personalizados por ventana (el control personalizado consta de varios bordes, bloques de texto y tiene aproximadamente un par de docenas de propiedades de dependencia). La cantidad de controles puede crecer. Pero ya esta cantidad lleva algunos incómodos segundos para visualizarse en la renderización inicial. Además, no proporciona un agradable desplazamiento suave cuando se aumenta el zoom. – rem
Me resulta difícil visualizar una IU con miles de cuadros de texto, todo al mismo tiempo frente al usuario. De todos modos, dependiendo de cómo esté todo arreglado, puede usar uno de los paneles de virtualización incorporados o escribir uno personalizado que solo creará los controles que son visibles. Eso debería acelerar las cosas de manera significativa. – NVM