Performances IOS - Animation de base, rendu hors écran et trace du système. 2e partie



Comment éviter les problèmes de performances avec le préréglage Core Animation, quoi utiliser pour tracer des sections de code et avec quelles fonctions pour réduire la part des opérations de calcul dans l'application de 26% à 0,6% - lisez la deuxième partie de l'article basée sur les matériaux du rapport de Luke Parham lors de la conférence MBLT DEV de l'année dernière . La première partie de l'article est disponible ici .


Sous le chat, non seulement des conseils utiles, mais aussi les derniers billets pour le lève- tôt pour MBLT DEV 2018 - vous ne pouvez les acheter qu'aujourd'hui.


Animation de base


Core Animation (CA) est un préréglage dans le profileur qui utilise des mesures FPS (images par seconde) pour voir si les animations sont en retard ou non. Souvent, même si des zones problématiques de l'application sont détectées, des difficultés de performances persistent. La raison en est que lorsque vous travaillez avec des cadres d'interface utilisateur, UIView est utilisé, mais une instance de CATransaction est créée sous le capot (ou le système le fait lui-même), et toutes ces instructions sont envoyées au serveur pour traitement. Le serveur de rendu est responsable de la création de l'animation. Si une animation est effectuée à l'aide d'une UIView, par exemple, la méthode de la classe animate(withDuration:animations:) , elle est traitée par le serveur de rendu, qui est considéré comme un thread séparé et fonctionne avec toutes les animations de l'application.


Vous pouvez faire fonctionner le serveur de rendu lentement afin qu'il n'apparaisse pas dans Time Profiler, mais cela ralentira toujours l'application. Voici à quoi ça ressemble:







En haut se trouve le capteur de fréquence d'images. Ci-dessous est la partie la plus importante - les options de débogage. Il existe deux paramètres clés et pourtant faciles à configurer. Le premier est color blended layers . Le réparer est assez simple. En fait, des problèmes surviennent même dans iMessage, l'application préférée d'Apple.




Le rouge indique les zones avec un fond blanc. Ils se chevauchent avec un autre fond blanc et, pour une raison quelconque, apparaissent transparents. Il s'avère que le programme mélange ces couleurs les unes avec les autres - blanc avec blanc, et le résultat est à nouveau blanc. Par conséquent, pour chaque pixel marqué en rouge, des calculs supplémentaires sont effectués qui n'apportent aucun avantage - un fond blanc est obtenu.


Règle n ° 3


Rendez les couches opaques dans la mesure du possible - à condition qu'elles aient les mêmes couleurs qui se chevauchent. Le calque possède la propriété d' opacity , qui doit être définie sur l'unité. Vérifiez toujours que la couleur d'arrière-plan est définie et qu'elle est opaque.




Rendu hors écran


L'option suivante est le rendu hors écran. Si vous activez cette fonction, les sections seront surlignées en jaune.

La commodité de Core Animation est la possibilité de visualiser d'autres applications. Vous pouvez activer les options, lancer l'application et voir ce qui ne va pas. Sur l'écran d'Instagram en haut, il y a de petits cercles jaunes dans lesquels les histoires de l'utilisateur sont affichées.




Par exemple, sur iPhone 6s, ils se chargent assez lentement. Et si vous les regardez sur l'iPhone 5 ou sur l'ancien modèle d'iPod, le téléchargement sera encore plus lent. Cela est dû au fait que le rendu intra-système est bien pire que le mélange alpha. Il charge le GPU. Par conséquent, l'appareil doit constamment effectuer des calculs supplémentaires entre le processeur graphique et le processeur central, de sorte que des retards supplémentaires peuvent être évités dans la plupart des cas.


Règle n ° 4


N'utilisez pas le paramètre cornerRadius . L'utilisation de viewLayer.cornerRadius entraîne un rendu hors écran. Au lieu de cela, vous pouvez utiliser la classe UIBezierPath , ainsi que quelque chose de similaire à travailler avec CGBitMap, comme c'était le cas avec le décodage JPEG auparavant. Dans ce cas, le UIGraphics context .




Il s'agit d'une autre méthode d'instance de la classe UIImage. Ici, vous pouvez définir la taille et créer des coins arrondis. Bezierpath est utilisé pour mettre en évidence une zone d'image. Ensuite, le fragment est renvoyé à partir de UIImageContext. Ainsi, nous obtenons l'image finale avec des coins arrondis au lieu d'arrondir les cadres dans lesquels l'image sera insérée.




Sur la page GIF - Twitter. Image affichée en temps réel. La page est censée s'ouvrir et fournir des informations, mais le texte et les autres éléments de l'écran ont subi un rendu hors écran, de sorte que les animations se déplacent très lentement.


Règle n ° 5


La propriété de la classe shouldRasterize de l'ensemble CALayer vous permet de mettre en cache les textures qui ont été rendues. Mieux vaut l'éviter. Si shouldRasterize pas été utilisé pendant un certain nombre de millisecondes, il quittera le cache et offrira le rendu de chaque image. Cela crée donc plus de problèmes que de bien.


Accélérez


  • Évitez le rendu hors écran et le mélange de calques transparents.
  • Utilisez-les uniquement lorsque vous ne pouvez pas vous en passer. Le rendu hors écran apparaît en raison de la présence d'ombres, d'arrondi des coins, etc.
  • Rendre les images opaques.
  • N'utilisez pas cornerRadius, utilisez les courbes de Bézier.
  • Lorsque vous travaillez avec du texte, n'utilisez pas la propriété layer.shadow, remplacez-la par NSShadow.


Trace d'activité


Le suivi d'activité est similaire à ce que fait Time Profiler, mais à plus petite échelle. Il vous permet de considérer les flux et leur interaction les uns avec les autres.

Règle n ° 6


Utilisez la trace du système pour suivre les périodes de temps pour des événements spécifiques. Vous pouvez trouver un moyen de retracer des événements ou des sections de code et de voir combien de temps ils prennent dans le vrai travail de l'application. System Trace fournit des informations sur ce qui se passe dans le système:


  • Le «Sing Post» signale que quelque chose d'important se produit.
  • Les marques sont des événements uniques qui valent la peine d'être regardés, par exemple, l'apparence d'une animation.
  • Par l'intervalle de l'événement, vous pouvez suivre la durée du décodage.




Ainsi, le programme montre comment le code interagit avec le reste du système.


Sur l'écran est un exemple de création d'un modèle de trace système:


  • 1 - téléchargement d'image
  • 2 - décodage d'image
  • 3 - animations d'inclinaison.

Vous devez ajouter quelques options pour comprendre quelle couleur se révélera. En règle générale, des numéros leur sont attribués, tels que 1 ou 2, et ils deviennent rouges ou verts, selon le paramètre. Sur Objective-C, vous devez écrire la commande #import pour kdebug_signpost . Dans Swift, ils sont déjà disponibles.




Ensuite, vous devez appeler cette fonction en kdebug_signpost ou kdebug_signpost_start et kdebug_signpost_end .




Nous indiquons 3 événements avec les nombres qui sont écrits dans le code, et un élément clé pour chaque événement spécifique. Le dernier chiffre indique la couleur. Par exemple, 2 est rouge.


Viennent ensuite les événements importants, les objets spéciaux. Un diagramme simplifié est décrit dans le projet de test de Luke sur Swift.


La capture d'écran montre à quoi elle ressemblera lorsque vous lancerez la trace. Au début, lorsque l'application est lancée, le programme ne donnera pas d'informations, mais dès que l'application se bloque, nous verrons les calculs.




Le téléchargement d'images prend environ 200 millisecondes. Vient ensuite le décodage, qui prend environ 40 millisecondes. Il est utile de garder une trace de ces données s'il existe de nombreuses opérations dans l'application. Vous pouvez répertorier les événements dans le programme, puis observer et recevoir des informations sur le temps nécessaire à leur mise en œuvre et sur la façon dont ils interagissent entre eux.


Des outils supplémentaires


Sur l'écran - Projet AR pour la prise de vue au ralenti d'un smartphone. L'application est similaire à Snapchat. Il a utilisé l'effet de retouche photo et pour chaque image, 26,4% de toutes les opérations informatiques ont été dépensées. Pour cette raison, l'appareil photo tournait lentement, environ 10 images par seconde. En étudiant, nous voyons que la ligne la plus haute a fait l'essentiel du travail. Elle était responsable de l'envoi actif des données. Si vous examinez les causes de l'affaissement des performances, vous remarquerez que le point est l'utilisation NSDispatchData de NSDispatchData .




Cette sous-classe de NSData reçoit uniquement une séquence d'octets à l'aide de la méthode getBytes dans un certain intervalle et la transmet à un autre emplacement. Cependant, cela semble si simple, tout ce que cette méthode fait en interne prend 18% de 26% des calculs.




Règle n ° 1


Utilisez NSData et getBytes . Il s'agit d'une opération simple sur Objective-C, mais si cela provoque des problèmes dans le système, vous devez basculer vers une fonction de niveau inférieur sur le simple C. Comme le problème consiste à obtenir des valeurs flottantes, vous pouvez utiliser la fonction de mémoire de copie. Avec lui, vous pouvez déplacer une donnée vers un autre emplacement. Cela économise considérablement la puissance de calcul de l'appareil.

NSData a de nombreuses opérations. Dans l'exemple, le code source est surligné en rouge. À l'aide de la fonction getBytes , getBytes pouvez convertir des données en nombres à virgule flottante. La méthode de copie de la mémoire est presque la même. Il est assez simple et effectue un ordre de grandeur moins d'opérations.




Si vous changez d'approche et redémarrez l'application, vous pouvez voir que le pourcentage des opérations de calcul dépensé pour changer la photo est passé de 26% à 0,6%. Et cela est dû au changement d'une seule ligne de code sur la copie de la mémoire. La fréquence d'images a considérablement augmenté.




Règle n ° 2


Évitez de superposer les pixels les uns sur les autres lors de la création d'une application dotée d'un rendu.

Dans la plupart des cas, cela se produit à une fréquence supérieure à 60 images par seconde. En utilisant CADisplayLink , vous pouvez ralentir la mise à jour de l'interface utilisateur. Il existe un paramètre préféréFramesPerSecond. Il ne s'applique qu'à iOS 10 et versions ultérieures. Pour les anciens systèmes, vous devez le faire manuellement. Lorsque vous travaillez dans de nouvelles versions d'iOS, vous pouvez définir le nombre d'images souhaité par seconde. Dans la plupart des cas, 15 images par seconde environ, afin de ne pas gaspiller la puissance de calcul et de ne pas ajouter de travail inutile à l'application.




Règle n ° 3


Lorsque vous travaillez avec Objective-C, il est utile d'utiliser la mise en cache des pointeurs IMP (pointeurs vers l'implémentation des méthodes). Lorsque la méthode under the hood est appelée dans Objective-C, la fonction objc_msgSend() est objc_msgSend() . Si la trace montre que l'appel prend une longue période, vous pouvez vous en débarrasser. En fait, il s'agit d'un référentiel de cache avec des pointeurs vers une fonction; on peut leur donner des noms de certaines méthodes. Par conséquent, au lieu d'effectuer cette recherche à chaque fois, il vaut la peine de procéder à la mise en cache comme suit: placez des pointeurs de fonction dans le cache et appelez-les directement. Cela se produit généralement deux fois plus vite.




S'il n'y a pas de pointeur, la méthode est appelée à l'aide de la commande methodForSelector. Pour appeler cette méthode d'aide de la fonction d'appel habituelle, vous devez entrer le nom de l'objet dans le sélecteur, qui produit les résultats de la recherche. Ce n'est peut-être pas le moyen le plus pratique mais le plus rapide.


Règle n ° 4


N'utilisez pas ARC (comptage automatique des références). ARC ajoute beaucoup de travail supplémentaire.


Lorsque l'ARC est activé, le compilateur proprement dit diffuse la retain / release aux bons endroits. Cependant, s'il existe des endroits où la retain et la release prennent trop de temps, envisagez de supprimer l'ARC. Faites-le si l'optimisation est nécessaire, car cela prendra beaucoup de temps.


Parfois, cela vaut la peine d’abandonner même Swift, surtout si les performances des applications sont sensibles aux changements. Swift a des fonctionnalités vraiment sympas, mais pour effectuer même de petites tâches, il nécessite d'écrire beaucoup de lignes de code afin d'atteindre un haut niveau de fonctionnalité.


Matériaux utiles


La première partie de l'article est disponible ici . Pour approfondir le sujet, Luke Parham recommande de lire le livre « iOS et MacOS: réglage des performances » et de regarder ses tutoriels .


L'enregistrement vidéo du rapport de Luke sur MBLT DEV 2017 est maintenant dans le domaine public:



Plus de connaissances et de conseils sur MBLT DEV 2018


Les premiers orateurs ont annoncé:


  • John C. Fox de Netflix parlera de localisation de haute qualité, travaillant avec des conditions de réseau agressives et des tests A / B.
  • Krzysztof Zabłocki, The New York Times, prépare un rapport sur les modèles dans iOS.
  • Laura Morinigo, Google Developer Expert, parle des meilleures pratiques Firebase.

Les derniers billets pour les lève-tôt s'envoleront aujourd'hui.


Source: https://habr.com/ru/post/fr415543/


All Articles