web-dev-qa-db-fra.com

Dans quel ordre les panneaux sont-ils les plus efficaces en termes de temps de rendu et de performances?

Il y a de nombreuses fois où plusieurs panneaux conviennent à la disposition que je souhaite, mais je sais qu'il existe une différence de temps de rendu pour différents types de panneaux.

Par exemple, MSDN indique que

Un Panel relativement simple, tel que Canvas, peut avoir des performances nettement meilleures qu'un Panel plus complexe, tel que Grid.

Donc, en termes de temps de rendu et de performances, dans quel ordre les panneaux WPF sont-ils les plus efficaces?

Panneaux WPF:

  • Canvas
  • DockPanel
  • Grid
  • UniformGrid
  • StackPanel
  • WrapPanel
  • VirtualizingPanel/VirtualizingStackPanel

Je suis presque sûr d'avoir vu une liste de cela quelque part en ligne, mais je ne la trouve pas maintenant.

La réponse idéale que je recherche me fournirait une liste de panneaux dans l'ordre de rendu le plus rapide. Je comprends que le nombre d'enfants est un facteur important dans l'efficacité des panneaux, donc pour cette question, supposons que chaque panneau n'a qu'une paire Label/TextBox.

En outre, je voudrais une liste d'exceptions, telles que des panneaux spécifiques qui fonctionnent mieux que d'autres en fonction de certaines conditions.

Mise à jour

Pour résumer en fonction de réponse acceptée ci-dessous, les performances du panneau sont basées sur le nombre et la disposition des éléments enfants, cependant en général la liste du plus rapide au plus lent est:

  • Canvas
  • StackPanel
  • WrapPanel
  • DockPanel
  • Grid

De plus, un VirtualizingPanel/VirtualizingStackPanel doit toujours être utilisé s'il y a beaucoup d'éléments qui ne tiennent pas toujours à l'écran.

Je vous recommande fortement de lire réponse acceptée ci-dessous pour plus de détails avant de choisir un élément de cette liste.

118
Rachel

Je pense qu'il est plus concis et compréhensible de décrire les caractéristiques de performance de chaque panneau que d'essayer de donner une comparaison de performance relative absolue.

WPF effectue deux passes lors du rendu du contenu: mesurer et organiser. Chaque panneau a des caractéristiques de performances différentes pour chacune de ces deux passes.

Les performances de la passe de mesure sont principalement affectées par la capacité d'un panneau à s'adapter à l'étirement à l'aide d'alignements (ou Auto dans le cas du Grid), puis du nombre d'enfants étirés ou dimensionnés automatiquement. Les performances de la passe Arrange sont affectées par la complexité de l'interaction entre l'emplacement de la disposition des différents enfants et ensuite bien sûr le nombre d'enfants.

Parfois, les panneaux donnés ne se prêtent pas facilement à la disposition requise. J'ai créé un contrôle qui avait besoin d'un nombre arbitraire d'éléments pour chacun être positionné à un certain pourcentage de l'espace disponible. Aucun des contrôles par défaut ne le fait. Tenter de les faire faire (via une liaison à la taille réelle du parent) entraîne des performances horribles. J'ai créé un panneau de disposition basé sur le canevas qui a atteint le résultat souhaité avec un minimum de travail (j'ai copié la source du canevas et modifié environ 20 lignes de celui-ci).

Panneaux disponibles:

  • Toile

    Définit une zone dans laquelle vous pouvez positionner explicitement les éléments enfants par des coordonnées relatives à la zone Canvas.

    Le canevas a les meilleures performances de tous les panneaux pour la passe d'arrangement, car chaque élément se voit attribuer statiquement un emplacement. La passe de mesure a également d'excellentes performances car il n'y a pas de concept d'étirement dans ce panneau; chaque enfant utilise simplement sa taille d'origine.

  • DockPanel

    Définit une zone dans laquelle vous pouvez organiser les éléments enfants horizontalement ou verticalement, les uns par rapport aux autres.

    Le Dockpanel a un schéma de mise en page très simple où les éléments sont ajoutés un par un par rapport à l'élément précédent ajouté. Par défaut, la hauteur ou la largeur est déterminée par la taille native de l'élément (basée respectivement sur Haut/Bas vs Gauche/Droite) et l'autre direction est déterminée par la propriété Dock si la largeur ou la hauteur n'est pas définie. Passe de mesure moyenne à rapide et passe d'agencement moyenne à rapide.

  • Grille

    Définit une zone de grille flexible composée de colonnes et de lignes.

    Il peut s'agir du panneau le plus gourmand en performances si un dimensionnement proportionnel ou un dimensionnement automatique est utilisé. Le calcul de la taille d'un élément enfant peut être une combinaison complexe de la taille native de l'élément et de la disposition spécifiée par la grille. La disposition est également la plus compliquée de tous les panneaux. Performances lentes à moyennes pour la passe de mesure et performances lentes à moyennes pour la passe d'arrangement.

  • StackPanel

    Organise les éléments enfants sur une seule ligne qui peut être orientée horizontalement ou verticalement.

    Le StackPanel mesure ses enfants en utilisant un dimensionnement natif ou relatif dans la direction opposée à son orientation et un dimensionnement natif dans la direction de son orientation (l'alignement ne fait rien dans cette direction). Cela en fait un artiste de niveau intermédiaire dans ce domaine. L'arrangement Arrangement est simplement, il suffit de disposer les articles dans l'ordre. Probablement la deuxième meilleure performance pour cette passe. Performances moyennes pour la passe de mesure et performances rapides pour la passe de mise en page.

  • VirtualizingPanel

    Fournit un cadre pour les éléments Panel qui virtualisent leur collecte de données enfants. Ceci est une classe abstraite.

    Une classe de base pour implémenter votre propre panneau de virtualisation. Charge uniquement les éléments visibles pour éviter une utilisation inutile de la mémoire et du processeur. BEAUCOUP plus performant pour les ensembles d'articles. Probablement légèrement moins performant pour les articles qui tiennent sur l'écran en raison de la vérification des limites. Le SDK n'en fournit qu'une seule sous-classe, le VirtualizingStackPanel.

  • WrapPanel

    Positionne les éléments enfants dans une position séquentielle de gauche à droite, coupant le contenu à la ligne suivante au bord de la boîte contenant. L'ordre suivant se produit séquentiellement de haut en bas ou de droite à gauche, selon la valeur de la propriété Orientation.

    La passe de mesure est une passe quelque peu complexe où le plus grand élément d'une ligne particulière détermine la hauteur de la ligne, puis chaque élément de cette ligne utilise sa hauteur native (si elle en a une) ou la hauteur de la ligne. La passe de mise en page est simple, en plaçant chaque élément l'un après l'autre sur une ligne, puis en continuant sur la ligne suivante lorsqu'il n'y a pas assez de place pour l'élément suivant. Passe de mesure de performance moyenne. Performance moyenne à rapide pour la passe d'arrangement.

Références:

Utilisez le panneau le plus efficace possible

La complexité du processus de disposition est directement basée sur le comportement de disposition des éléments dérivés du panneau que vous utilisez. Par exemple, un contrôle Grid ou StackPanel fournit beaucoup plus de fonctionnalités qu'un contrôle Canvas. Le prix de cette augmentation plus importante des fonctionnalités est une augmentation plus importante des coûts de performance. Toutefois, si vous n'avez pas besoin des fonctionnalités fournies par un contrôle Grid, vous devez utiliser les alternatives moins coûteuses, telles qu'un canevas ou un panneau personnalisé.

De Optimisation des performances: mise en page et conception

Le système de mise en page complète deux passes pour chaque membre de la collection Enfants, une passe de mesure et une passe d'arrangement. Chaque panneau enfant fournit ses propres méthodes MeasureOverride et ArrangeOverride pour obtenir son propre comportement de disposition spécifique.

Lors du passage de mesure, chaque membre de la collection Enfants est évalué. Le processus commence par un appel à la méthode Measure. Cette méthode est appelée dans l'implémentation de l'élément Panel parent et ne doit pas être appelée explicitement pour que la mise en page se produise.

Tout d'abord, les propriétés de taille native de UIElement sont évaluées, telles que Clip et Visibilité. Cela génère une valeur nommée constraintSize qui est transmise à MeasureCore.

Deuxièmement, les propriétés de framework définies sur FrameworkElement sont traitées, ce qui affecte la valeur de constraintSize. Ces propriétés décrivent généralement les caractéristiques de dimensionnement de l'élément UIElement sous-jacent, telles que sa hauteur, sa largeur, sa marge et son style. Chacune de ces propriétés peut modifier l'espace nécessaire pour afficher l'élément. MeasureOverride est ensuite appelé avec constraintSize comme paramètre.

Remarque Il existe une différence entre les propriétés Hauteur et Largeur et ActualHeight et ActualWidth. Par exemple, la propriété ActualHeight est une valeur calculée basée sur d'autres entrées de hauteur et le système de disposition. La valeur est définie par le système de mise en page lui-même, sur la base d'une passe de rendu réelle, et peut donc être légèrement en retard par rapport à la valeur définie des propriétés, telles que la hauteur, qui sont à la base du changement d'entrée. Étant donné qu'ActualHeight est une valeur calculée, vous devez savoir qu'il peut y avoir des modifications signalées multiples ou incrémentielles à la suite de diverses opérations par le système de disposition. Le système de disposition peut calculer l'espace de mesure requis pour les éléments enfants, les contraintes par l'élément parent, etc. Le but ultime de la passe de mesure est que l'enfant détermine sa taille souhaitée, qui se produit lors de l'appel de MeasureCore. La valeur DesiredSize est stockée par Measure pour être utilisée lors de la passe d'arrangement de contenu.

La passe d'arrangement commence par un appel à la méthode Arrange. Pendant la passe d'arrangement, l'élément Panel parent génère un rectangle qui représente les limites de l'enfant. Cette valeur est transmise à la méthode ArrangeCore pour le traitement.

La méthode ArrangeCore évalue la DesiredSize de l'enfant et évalue toutes les marges supplémentaires qui peuvent affecter la taille rendue de l'élément. ArrangeCore génère un arrangementSize, qui est transmis à la méthode ArrangeOverride du Panel en tant que paramètre. ArrangeOverride génère la taille finale de l'enfant. Enfin, la méthode ArrangeCore effectue une évaluation finale des propriétés de décalage, telles que la marge et l'alignement, et place l'enfant dans son emplacement de disposition. L'enfant n'a pas à remplir (et souvent pas) l'espace entier alloué. Le contrôle est ensuite renvoyé au panneau parent et le processus de mise en page est terminé.

De Mesurer et organiser les enfants

121
mydogisbox

Peut-être que ceci vous aidera.

Non seulement pour les panneaux mais aussi pour chaque application que vous souhaitez créer dans WPF.

Il conclut les performances de dessin et de mesure de WPF.

Il contient également une application de test de dessin, des résultats et des conclusions pour les différents systèmes d'exploitation que vous souhaitez cibler.

11
mike_sev

Les panneaux que vous mentionnez sont des panneaux de disposition, donc un bref aperçu du système de disposition suggère qu'il ne s'agira probablement pas d'une simple liste des panneaux les plus efficaces, mais de la façon dont vous utilisez les panneaux qui ont le plus grand effet sur l'efficacité et les performances.

LayoutSystem_Overview :

Dans sa plus simple expression, la mise en page est un système récursif qui conduit à dimensionner, positionner et dessiner un élément. Plus précisément, la mise en page décrit le processus de mesure et d'organisation des membres de la collection Children d'un élément Panel. La mise en page est un processus intensif. Plus la collection Enfants est grande, plus le nombre de calculs à effectuer est important. La complexité peut également être introduite en fonction du comportement de mise en page défini par l'élément Panel propriétaire de la collection. Un panneau relativement simple, tel que Canvas, peut avoir des performances nettement meilleures qu'un panneau plus complexe, tel que Grid.

Chaque fois qu'un UIElement enfant change de position, il a le potentiel de déclencher un nouveau passage par le système de disposition. Par conséquent, il est important de comprendre les événements qui peuvent appeler le système de disposition, car un appel inutile peut entraîner de mauvaises performances de l'application. Ce qui suit décrit le processus qui se produit lorsque le système de disposition est appelé.

1. Un UIElement enfant commence le processus de mise en page en mesurant d'abord ses propriétés principales.

2. Les propriétés de dimensionnement définies sur FrameworkElement sont évaluées, telles que la largeur, la hauteur et la marge.

3. Une logique spécifique au panneau est appliquée, telle que la direction du Dock ou l'orientation de l'empilement.

4. Le contenu est organisé après que tous les enfants ont été mesurés.

5. La collection Enfants est dessinée à l'écran.

6. Le processus est à nouveau appelé si des enfants supplémentaires sont ajoutés à la collection, un LayoutTransform est appliqué ou la méthode UpdateLayout est appelée.

Voir LayoutSystem_Measure_Arrange pour plus d'informations sur la mesure et l'organisation des enfants

LayoutSystem_Performance :

La mise en page est un processus récursif. Chaque élément enfant d'une collection Enfants est traité lors de chaque appel du système de disposition. Par conséquent, le déclenchement du système de mise en page doit être évité lorsqu'il n'est pas nécessaire. Les considérations suivantes peuvent vous aider à obtenir de meilleures performances.

Soyez conscient des changements de valeur de propriété qui forceront une mise à jour récursive par le système de disposition.

Les propriétés de dépendance dont les valeurs peuvent provoquer l'initialisation du système de disposition sont marquées par des indicateurs publics. AffectsMeasure et AffectsArrange fournissent des indices utiles sur les changements de valeur de propriété qui forceront une mise à jour récursive par le système de disposition. En général, toute propriété qui peut affecter la taille du cadre de délimitation d'un élément doit avoir un indicateur AffectsMeasure défini sur true. Pour plus d'informations, consultez Vue d'ensemble des propriétés de dépendance.

Lorsque cela est possible, utilisez un RenderTransform au lieu d'un LayoutTransform.

Un LayoutTransform peut être un moyen très utile d'affecter le contenu d'une interface utilisateur (UI). Cependant, si l'effet de la transformation n'a pas à influer sur la position des autres éléments, il est préférable d'utiliser un RenderTransform à la place, car RenderTransform n'appelle pas le système de disposition. LayoutTransform applique sa transformation et force une mise à jour récursive de la mise en page pour tenir compte de la nouvelle position de l'élément affecté.

Évitez les appels inutiles à UpdateLayout.

La méthode UpdateLayout force une mise à jour récursive de la disposition et n'est souvent pas nécessaire. Sauf si vous êtes sûr qu'une mise à jour complète est requise, comptez sur le système de disposition pour appeler cette méthode pour vous.

Lorsque vous travaillez avec une grande collection Children, envisagez d'utiliser un VirtualizingStackPanel au lieu d'un StackPanel normal.

En virtualisant la collection enfant, VirtualizingStackPanel conserve uniquement les objets en mémoire qui se trouvent actuellement dans le ViewPort du parent. Par conséquent, les performances sont considérablement améliorées dans la plupart des scénarios.

Optimizing Performance: Layout and Design : Cet article explique en détail comment construire efficacement l'arborescence et donne une liste simple de panneaux en fonction de leur complexité

Canvas (moins complexe = performances plus efficaces et meilleures)

La grille

Autres panneaux (plus complexes = performances moins efficaces et moins bonnes)

Autres considérations de performances à prendre en compte: façons d'améliorer la vitesse de rendu de l'interface utilisateur WPF

  1. Cachez tout. Pinceaux, couleurs, géométries, textes formatés, glyphes. (Par exemple, nous avons deux classes: RenderTools et TextCache. Le 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 n'est exécutée qu'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 façons de rendre le texte, mais la plus rapide est DrawingContext.DrawGlyphs.
  4. Activez le recyclage des conteneurs. La virtualisation apporte de nombreuses améliorations de performances, mais les conteneurs seront supprimés et recréés, c'est la valeur par défaut. Mais vous pouvez gagner plus de performances en recyclant les conteneurs en définissant VirtualizingStackPanel.VirtualizationMode = "Recycling"
  5. De ici : Il n'y a pas de limite pratique à la quantité d'imbrication que votre application peut prendre en charge, cependant, il est généralement préférable de limiter votre application à n'utiliser que les panneaux qui sont réellement nécessaires pour la mise en page souhaitée. Dans de nombreux cas, un élément Grid peut être utilisé à la place des panneaux imbriqués en raison de sa flexibilité en tant que conteneur de disposition. Cela peut augmenter les performances de votre application en gardant les éléments inutiles hors de l'arborescence.
7
Erick