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

127

Il y a de nombreuses fois où plus d'un panneau conviendrait à la mise en page que je veux, mais je sais qu'il y a une différence dans les temps de rendu pour différents types de panneaux.

Par exemple, MSDN déclare que

Un relativement simple Panel, tel que Canvas, peut avoir des performances nettement meilleures qu'un plus complexe Panel, 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 à peu près sûr d'avoir vu une liste de cela quelque part en ligne, mais je ne peux pas la trouver maintenant.

La réponse idéale que je recherche serait de me fournir une liste de panneaux dans l'ordre où ils seraient rendus le plus rapidement. Je comprends que le nombre d'enfants est un facteur important dans l'efficacité des panneaux, donc pour le bien de cette question, supposez que chaque panneau n'a qu'un Label/TextBox paire .

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.

Mettre à jour

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

  • Canvas
  • StackPanel
  • WrapPanel
  • DockPanel
  • Grid

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

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

Rachel
la source
Est-il naïf de supposer que les panneaux de virtualisation seront invariablement plus performants que les panneaux non virtualisés?
BoltClock
@BoltClock Je pense que cela dépend de la quantité de contenu non visible dans le panneau. S'il y a beaucoup d'éléments non visibles, VirtualizingStackPanelcela fonctionnera certainement mieux, mais si tous les éléments affichés dans le panneau sont visibles, je pense qu'il est préférable d'utiliser un panneau normal.
Rachel
Merci. Il est logique que ce soit un gaspillage d'éléments de virtualisation, alors que tous s'afficheront de toute façon.
BoltClock
À part la virtualisation, ils ont des fonctionnalités différentes ou ils ne seraient pas des contrôles séparés. Je vais avec ce qui fournit la meilleure interface utilisateur au client.
paparazzo
1
Êtes-vous sûr qu'il y a une différence notable (à part la virtualisation)? Tout ce qu'ils ont à faire est d'exécuter un algorithme de mise en page relativement léger. Minuscule par rapport à tout le rendu qui va suivre. Cela dit, la grille sera probablement la plus lente (mise à l'échelle pondérée).
Henk Holterman

Réponses:

130

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 Réorganiser. Chaque panneau a des caractéristiques de performance différentes pour chacune de ces deux passes.

Les performances de la passe de mesure sont les plus affectées par la capacité d'un panneau à s'adapter à l'étirement à l'aide d'alignements (ou Auto dans le cas de Grid), puis au nombre d'enfants étirés ou auto-dimensionnés. La performance de la passe Arrange est affectée par la complexité de l'interaction entre l'emplacement de mise en page 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 nécessaire. J'ai créé un contrôle qui nécessitait 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 leur faire faire cela (via la liaison à la taille réelle du parent) entraîne des performances horribles. J'ai créé un panneau de mise en page basé sur le canevas qui a obtenu 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 du canevas.

    Le canevas a les meilleures performances de tous les panneaux pour la passe d'arrangement puisque chaque élément se voit attribuer un emplacement de manière statique. 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 native.

  • 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 Dockpropriété si la largeur ou la hauteur n'est pas définie. Passe de mesure moyenne à rapide et passe de disposition moyenne à rapide.

  • la grille

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

    Ce panneau peut être le plus performant si le dimensionnement proportionnel ou le dimensionnement automatique est utilisé. Le calcul de la taille de l'é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 mise en page est également le plus compliqué 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 en 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 le sens de son orientation (l'alignement ne fait rien dans cette direction). Cela en fait un artiste de niveau intermédiaire dans ce domaine. Le pass Arrangement consiste simplement à disposer les éléments 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 collection 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 un peu moins performant pour les éléments qui tiennent sur l'écran en raison de la vérification des limites. Le SDK ne fournit qu'une sous-classe de ceci, le VirtualizingStackPanel.

  • WrapPanel

    Positionne les éléments enfants en position séquentielle de gauche à droite, en coupant le contenu sur la ligne suivante au bord de la boîte contenant. L'ordre suivant se produit de manière séquentielle 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ù l'élément le plus grand d'une ligne particulière détermine la hauteur de la ligne, puis chaque élément de cette ligne utilise sa hauteur native (s'il en a une) ou la hauteur de la ligne. La passe de mise en page est simple: placer chaque élément l'un après l'autre sur une ligne, puis passer à la ligne suivante lorsqu'il n'y a pas assez de place pour l'élément suivant. Passe de mesure de performance moyenne. Performances moyennes à rapides pour la passe d'arrangement.

Références:

Utilisez le panneau le plus efficace lorsque cela est possible

La complexité du processus de mise en page est directement basée sur le comportement de mise en page des éléments dérivés du Panel 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 plus grande augmentation 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 les moins coûteuses, telles qu'un canevas ou un panneau personnalisé.

De l' optimisation des performances: mise en page et conception

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

Pendant la passe de mesure, chaque membre de la collection Children 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 n'a pas besoin d'être appelée explicitement pour que la mise en page se produise.

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

Deuxièmement, les propriétés de cadre 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 de Height et Width 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 disposition lui-même, en fonction 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 Hauteur, qui sont à la base de la modification d'entrée. Étant donné qu'ActualHeight est une valeur calculée, vous devez savoir qu'il peut y avoir des modifications rapportées multiples ou incrémentielles à la suite de diverses opérations effectuées par le système de disposition. Le système de mise en page peut calculer l'espace de mesure requis pour les éléments enfants, les contraintes de l'élément parent, etc. Le but ultime de la passe de mesure est que l'enfant détermine sa taille désirée, qui se produit pendant l'appel de MeasureCore. La valeur DesiredSize est stockée par Measure pour être utilisée pendant la passe d'arrangement du 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 traitement.

La méthode ArrangeCore évalue le DesiredSize de l'enfant et évalue toutes les marges supplémentaires qui peuvent affecter la taille de rendu de l'élément. ArrangeCore génère un arrangementSize, qui est passé à la méthode ArrangeOverride du Panel en tant que paramètre. ArrangeOverride génère le finalSize 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 ne le fait pas) tout l'espace alloué. Le contrôle est ensuite renvoyé au panneau parent et le processus de mise en page est terminé.

De la mesure et de l'organisation des enfants

N / A
la source
1
En réponse à un commentaire maintenant supprimé: je n'ai pas inclus de métriques car elles ne seraient pas utiles. Il y a trop de combinaisons pour qu'une feuille de calcul soit utile. Une méthode plus utile pour optimiser les performances consisterait à utiliser une compréhension générale pour choisir les panneaux de disposition initiale, puis à les optimiser au besoin à partir de là en utilisant une analyse de la situation réelle.
N_A
Merci, votre explication sur la façon dont les panneaux WPF sont réellement rendus, et les performances de mesure / organisation de chaque panneau sont bien meilleures que ce que je demandais :)
Rachel
@mydogisbox Je ne vois UniformGridnulle part sur votre liste. Seriez-vous en mesure de mettre à jour votre réponse avec ce panneau et ses performances estimées de mesure / organisation par rapport aux autres types de panneaux?
Rachel
1
@Rachel Le UniformGridn'est pas destiné à être utilisé dans la mise en page d'application. Voir «Éléments de panneau dérivés» ici: msdn.microsoft.com/en-us/library/ms754152.aspx pour plus d'informations. En termes de vitesse, il devrait être légèrement plus rapide que a DockPanelet légèrement plus lent que a Canvas.
N_A
12

Peut - être que cela vous aidera.

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

Il conclut le dessin WPF et la mesure des performances.

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

mike_sev
la source
8

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 forme la plus simple, la mise en page est un système récursif qui conduit à dimensionner, positionner et dessiner un élément. Plus spécifiquement, 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 Children est grande, plus le nombre de calculs à effectuer est important. La complexité peut également être introduite en fonction du comportement de disposition défini par l'élément Panel qui possède la collection. Un Panel relativement simple, tel que Canvas, peut avoir des performances nettement meilleures qu'un Panel plus complexe, tel que Grid.

Chaque fois qu'un UIElement enfant change de position, il a le potentiel de déclencher une nouvelle passe 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 une invocation 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 de base.

2. Les propriétés de dimensionnement définies sur FrameworkElement sont évaluées, telles que Largeur, Hauteur et Marge.

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

4. Le contenu est organisé une fois que tous les enfants ont été mesurés.

5. La collection Children 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 si 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 Children est traité lors de chaque appel du système de disposition. En conséquence, 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 mise en page.

Les propriétés de dépendance dont les valeurs peuvent entraîner l'initialisation du système de disposition sont marquées avec 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 mise en page. En général, toute propriété qui peut affecter la taille du cadre de sélection 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). Toutefois, si l'effet de la transformation ne doit pas avoir d'impact sur la position d'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 disposition 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 de la disposition récursive et n'est souvent pas nécessaire. Sauf si vous êtes sûr qu'une mise à jour complète est nécessaire, comptez sur le système de mise en page 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 ne conserve en mémoire que les objets qui se trouvent actuellement dans le ViewPort du parent. En conséquence, les performances sont considérablement améliorées dans la plupart des scénarios.

Optimisation des performances: mise en page et conception : cet article explique en détail comment créer efficacement l'arborescence et donne une liste simple de panneaux en fonction de leur complexité

Canvas (le moins complexe = plus efficace et de meilleures performances)

la grille

Autres panneaux (plus complexes = moins efficaces et moins performants)

Autres considérations de performances à prendre en compte: Moyens 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 une 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 méthodes de rendu les plus rapides de chaque primitive. Par exemple, il existe environ 6 méthodes de rendu de 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. À partir de : 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 pour 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 de 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.
Erick
la source
2
Cette réponse consiste presque entièrement à copier et coller à partir d'autres sources, certaines non attribuées. Ce serait beaucoup mieux si vous le réduisiez aux seules parties pertinentes, attribuiez correctement toutes les sources et tentiez de répondre plus directement à la question.
N_A
2
@mydogisbox La réponse est une compilation d'informations, plusieurs des mêmes sites que vous avez utilisés dans votre réponse, pourrais-je ajouter. Pour ne pas prendre en considération d'autres aspects qui modifient les performances peuvent conduire à une réponse incomplète ou au demandeur ayant encore des questions supplémentaires, j'ai donc choisi de les inclure. Bien que Rachel avec un incroyable représentant de 21,7K et une grande expérience WPF puisse déjà connaître ces informations, d'autres personnes qui examinent cette question peuvent souhaiter ces informations supplémentaires et relivantes avec la réponse.
Erick