web-dev-qa-db-fra.com

Comment améliorer la vitesse de rendu de l'interface utilisateur WPF

Dans le cas où un écran d'une application WPF contient beaucoup de contrôles primitifs, son rendu devient lent. Quels sont les moyens recommandés pour améliorer la réactivité d'une application WPF dans un tel cas, en plus d'ajouter moins de contrôles et d'utiliser une carte vidéo plus puissante?

Existe-t-il un moyen d'utiliser la mise en mémoire tampon hors écran ou quelque chose comme ça?

41
rem

Notre équipe a été confrontée à des problèmes de performances de rendu. Dans notre cas, nous avons environ 400 unités de transport et nous devons rendre le graphique de chaque unité avec beaucoup de détails (étiquettes de texte, marques spéciales, géométries différentes, etc.).

Dans nos premières implémentations, nous avons divisé chaque graphique en primitives et composé le graphique de l'unité entière via Binding. C'était une très triste expirience. La réaction de l'interface utilisateur a été extrêmement lente.

Nous avons donc décidé de créer n élément d'interface utilisateur pour chaque unité et de rendre le graphique avec DrawingContext. Bien que ce soit beaucoup mieux en termes de performances, nous avons passé environ un mois à améliorer le rendu.

Quelques conseils:

  1. Cachez tout. Pinceaux, couleurs, géométries, textes formatés, glyphes. (Par exemple, nous avons deux classes: RenderTools et TextCache. Processus de rendu de chaque unité adresse à l'instance partagée des deux classes. Donc, si deux graphiques ont le même texte, sa préparation est exécutée une seule fois .)
  2. Freeze Freezable, si vous prévoyez de l'utiliser pendant une longue période. Surtout les géométries. Les géométries complexes non gelées exécutent HitTest extrêmement lentement.
  3. Choisissez les moyens les plus rapides de rendu de chaque primitive. Par exemple, il existe environ 6 modes de rendu de texte, mais le plus rapide est DrawingContext.DrawGlyphs.
  4. Utilisez le profileur pour découvrir les points chauds. Par exemple, dans notre projet, nous avions un cache de géométries et rendu approprié à la demande. Il semblait être qu'aucune amélioration n'est possible. Mais un jour, nous avons pensé que si nous rendions les géométries une fois et mettions en cache des visuels prêts? Dans notre cas, une telle approche s'est avérée acceptable. Le graphique de notre unité ne comporte que plusieurs états. Lorsque les données du graphique sont modifiées, nous reconstruisons DrawingVisual pour chaque état et les mettons en cache.

Bien sûr, cette façon nécessite des investissements, c'est un travail ennuyeux et ennuyeux, mais le résultat est génial.

Soit dit en passant: lorsque nous avons activé l'option de mise en cache WPF (vous pouvez trouver un lien dans les réponses), notre application a raccroché.

50
Alex Zhevzhik

J'ai eu le même problème de perf avec un datagrid fortement personnalisé depuis un an, et ma conclusion est:

il n'y a pratiquement rien que vous puissiez faire de votre côté (sans affecter votre application, c'est-à-dire: avoir moins de contrôles ou utiliser uniquement des styles par défaut)

Le lien mentionné par Jens est génial mais inutile dans votre cas.

Le lien "Optimiser les performances des applications WPF" fourni par NVM est presque également inutile dans mon expérience: il fait appel au bon sens et je suis convaincu que vous n'apprendrez rien d'extraordinaire non plus. Sauf une chose peut-être: Je dois dire que ce lien m'a appris à mettre autant que possible dans la ressource de mon application. Parce que WPF ne rétablit rien de ce que vous mettez dans la ressource, il réutilise simplement la même ressource encore et encore. Alors mettez autant que vous le pouvez (styles, pinceaux, modèles, polices ...)

dans l'ensemble, il n'y a tout simplement aucun moyen d'accélérer les choses dans WPF simplement en cochant une option ou en désactivant une autre. Vous pouvez simplement prier MS de retravailler sa couche de rendu dans un avenir proche pour l'optimiser et en attendant, essayez de réduire votre besoin d'effets, de commandes personnalisées, etc.

7
David

Jetez un œil à la nouvelle option de mise en cache (.NET 4.0). (Voir ici .)

3
Jens