J'ai mené une enquête approfondie sur les performances de UICollectionView. La conclusion est simple. Les performances sont médiocres pour un grand nombre de cellules.
EDIT : Mes excuses, je viens de relire votre message, le nombre de cellules que vous avez devrait être correct (voir le reste de mon commentaire), donc la complexité des cellules peut aussi être un problème.
Si votre conception le permet, vérifiez :
-
Chaque cellule est opaque.
-
Le contenu des cellules s'accroche aux limites.
-
Les coordonnées des cellules ne contiennent pas de valeurs fractionnaires (par exemple, elles sont toujours calculées comme des pixels entiers).
-
Essayez d'éviter les chevauchements de cellules.
-
Essayez d'éviter les ombres portées.
La raison en est en fait très simple. Beaucoup de gens ne la comprennent pas, mais elle vaut la peine d'être comprise : Les UIScrollViews n'utilisent pas de Core Animation pour défiler. Ma croyance naïve était qu'elles impliquaient une "sauce" secrète d'animation de défilement et qu'elles demandaient simplement des mises à jour occasionnelles aux délégués de temps en temps pour vérifier le statut. Mais en fait, les vues de défilement sont des objets qui n'appliquent directement aucun comportement de dessin. Tout ce qu'ils sont vraiment, c'est une classe qui applique une fonction mathématique abstraite du placement des coordonnées des UIViews qu'ils contiennent, de sorte que les coordonnées des vues sont traitées comme relatives à un plan abstrait de ContentView plutôt que relatives à l'origine de la vue qui les contient. Une vue défilante mettra à jour la position du plan de défilement abstrait en fonction de l'entrée de l'utilisateur (par exemple, le balayage) et, bien sûr, il y a aussi un algorithme physique qui donne un "momentum" aux positions des coordonnées traduites.
Maintenant, si vous deviez produire votre propre objet de mise en page de vue de collection, en théorie, vous pourriez en produire un qui inverse à 100% la translation mathématique appliquée par la vue de défilement sous-jacente. Ce serait intéressant mais inutile, car il semblerait alors que les cellules ne bougent pas du tout lorsque vous les faites glisser. Mais je soulève cette possibilité parce qu'elle illustre le fait que l'objet de mise en page de la vue de collection travaillant avec l'objet de vue de collection lui-même effectue une opération très similaire à celle du scrollview sous-jacent. Par exemple, il offre simplement la possibilité d'appliquer une traduction mathématique supplémentaire, image par image, des attributs des vues à afficher, et dans la plupart des cas, il s'agira d'une simple traduction des attributs de position.
Ce n'est que lorsque de nouvelles cellules sont insérées, supprimées, déplacées ou rechargées que CoreAnimation intervient, le plus souvent en appelant :
- (void)performBatchUpdates:(void (^)(void))updates
completion:(void (^)(BOOL finished))completion
UICollectionView demande les attributs de mise en page des cellules pour chaque image de défilement et chaque vue visible est mise en page pour chaque image. Les UIView sont des objets riches optimisés pour la flexibilité plus que pour les performances. Chaque fois qu'une vue est disposée, le système effectue un certain nombre de tests pour vérifier son alpha, son zIndex, ses sous-vues, ses attributs d'écrêtage, etc. La liste est longue. Ces vérifications et les modifications de la vue qui en résultent sont effectuées pour chaque élément de vue de la collection pour chaque image.
Pour garantir de bonnes performances, toutes les opérations image par image doivent être effectuées dans un délai de 17 ms. [J'ai mis cette clause entre crochets car j'ai relu votre message et je me suis rendu compte que je l'avais mal lu. Avec le nombre de cellules que vous avez, il ne devrait pas y avoir de problème de performance. J'ai personnellement constaté qu'avec un test simplifié avec des cellules vanille, contenant une seule image en cache, la limite testée sur un iPad 3 est d'environ 784 cellules à l'écran avant que les performances ne commencent à chuter en dessous de 50 images par seconde.
Dans la pratique, vous devrez rester en deçà de cette valeur.
Personnellement, j'utilise mon propre objet de mise en page personnalisé et j'ai besoin de performances plus élevées que celles fournies par UICollectionView. Malheureusement, je n'ai exécuté le test simple ci-dessus qu'à un certain stade du développement et j'ai réalisé qu'il y avait des problèmes de performances. Je vais donc retravailler le back-port open source de UICollectionView, PSTCollectionView. Je pense qu'il existe une solution de contournement qui peut être mise en œuvre de sorte que, juste pour le défilement général, la couche de chaque élément de cellule est écrite en utilisant une opération qui contourne la mise en page de chaque cellule UIView. Cela fonctionnera pour moi puisque j'ai mon propre objet de mise en page, et je sais quand la mise en page est nécessaire et j'ai une astuce qui permettra au PSTCollectionView de revenir à son mode de fonctionnement normal à ce moment-là. J'ai vérifié la séquence d'appels et elle ne semble pas être trop complexe, ni du tout irréalisable. Mais il est certain que ce n'est pas trivial et que d'autres tests doivent être effectués avant que je puisse confirmer que cela fonctionnera.
0 votes
Non, vous n'avez pas tort. Mes tests avec un objet vanilla UICollectionView utilisant Flowlayout et un simple tableau de cellules allouées statiquement contenant des objets de visualisation d'images, montrent que vous pouvez facilement atteindre 100 cellules sans problème de performance. Avec une configuration classique sur un iPad 3, il faut s'attendre à des problèmes de performances à partir de 700 cellules.
1 votes
Dans mon cas, les fonctions liées à NSDate prennent trop de temps...
0 votes
Pouvez-vous expliquer comment vous avez créé votre vue de collection de cellules vanille ? Sur l'iPad 3, les cellules ne contiennent qu'une seule image (la même pour toutes les cellules), même avec 50 cellules ce n'est pas complètement lisse, et complètement inutilisable au-delà de 150 cellules. De plus, quand je dis 150 cellules, je veux dire visibles à la fois sur l'écran, pas dans l'ensemble des données. Avec 30 cellules à l'écran, je peux facilement maintenir la fluidité même avec des ensembles de données énormes (100K+).