Réduire le poids des applications Xamarin

Il s’agit ici d’une partie sur un retour d’une formation que j’avais obtenue à Reading en Angleterre. Après l’avoir reçue, j’ai alors animé un Meetup à Paris pour la communauté Cross-Platform Native Mobile Development in Paris dont le thème était développement Xamarin avancé. Le but de cet article est de revenir de façon détaillée sur des techniques permettant de publier une application plus séduisante : fluide, qui ne plante PAS (ou pas trop vite) et la plus légère possible. Quelques autres petites astuces seront également données au passage.
Xamarin, un argument de poids
Pour introduire le sujet, sachez que tous les jours de nombreuses personnes se demandent quelle application sera désinstallée pour pouvoir prendre une photo, une vidéo ou télécharger une autre application. Si le poids de votre application est trop important par rapport à sa fonction, elle risque fort d’être la malheureuse élue. Mais le poids d’une application entre également en jeu dans deux autres scénarios : au téléchargement, ainsi qu’à l’utilisation. Ce facteur est donc un critère important à prendre en compte quand on développe une application et qu’on se soucie de ses utilisateurs.
Le Linker
Xamarin présente l’inconvénient de rajouter un peu de poids aux packages dans le store. En effet, afin de pouvoir utiliser le C# et le Framework .Net, on embarque un composant qui va alourdir l’application, ainsi que les bibliothèques tierces permettant gagner du temps et éviter de refaire la roue, qui ont elles-mêmes des dépendances. Xamarin en a conscience et pour cela a mis en place un outil : le Linker.

Il fonctionne avec trois options :
- Don’t link (Par défaut)
- Link Framework SDKs Only
- Link All
L’option par défaut “Don’t link” permet de ne rien retirer, ainsi on récupère tout et le package peut être ENORME ! La seconde valeur va permettre de retirer tout ce dont on ne se sert pas dans le Framework uniquement. La dernière valeur va alors vérifier tous nos packages pour aller retirer tout ce qui est inutile. Attention cependant, l’utilisation de la reflection fait que les références ne sont pas explicites et que ces dernières ne seront pas packagées. Il faudra alors appliquer manuellement une dérogation explicite en plaçant un attribut [Preserve (Conditional=true)]
sur la classe ou le membre dont on veut préserver les références, ou utiliser des arguments mtouch sur iOS.
La documentation détaillée se trouve ici : https://developer.xamarin.com/guides/ios/advanced_topics/linker/
Les packages
Un bon développeur est fait au plus simple (KISS : keep it simple and stupid) et n’aime pas réinventer la roue. Il consomme naturellement des packages NuGet exposant des fonctionnalités qui l’intéressent. Cependant ceci à un coût. Premièrement, l’application va se retrouver à peser très lourd, comme on vient de le voir juste au-dessus. Deuxièmement, le nombre de références très élevé risque de forcer le Multi-dex sur Android, une fonctionnalité plutôt lourde qui permet d’exécuter une application en x64 et augmenter le nombre de références qu’il est possible d’avoir (aujourd’hui impossible à atteindre).
Il est donc important de vérifier systématiquement lors de l’ajout d’un package si celui-ci ne va pas intégrer par capillarité beaucoup trop de dépendances qui augmentent le poids du résultat.
Images
Afin de rendre son application toujours plus sexy, nous autres avons l’habitude d’avoir beaucoup d’images. Cependant, suivant comment nous développons l’application, celles-ci peuvent être inadaptées à la situation. Les tailles sont parfois démesurées, ou alors ridiculement petites. Ceci a une influence directe non seulement sur la taille du package mais aussi sur les performances de l’application. Elle devra en effet alors recalculer une taille adaptée pour chaque image. Ce traitement peut parfois être couteux. Heureusement Android comme iOS disposent de méthodes très similaires pour résoudre ce problème.
Il s’agit de mettre à disposition la même image avec des tailles différentes. Ainsi iOS propose d’avoir des tailles de type :
- @1x
- @2x
- @3x
Tandis qu’Android propose :
- hdpi
- mdpi
- nodpi
- xhdpi
- xxhdpi
Ainsi, si, en rajoutant des images pour chacune des tailles, votre package sera très gros, l’utilisateur, lui, ne va télécharger que le contenu dont il a besoin, et l’application n’aura plus de traitement d’image à faire lors de l’exécution.
De plus, une image contient des métadonnées EXIF. Elles peuvent être nombreuses et sont souvent inutiles dans le cadre d’une application mobile. Si cela prend quelques kilooctets pour une image seule, cela peut représenter plusieurs mégaoctets sur la totalité. Il existe de très nombreux logiciels pour nettoyer vos médias, n’hésitez pas à les utiliser.

LLVM
Il s’agit d’une option de compilation qui permet de se passer de Mono Code Generation Engine. Cette option seulement utilisable en mode de compilation Release, réduit la taille des packages et améliore les performances globales de l’application au détriment d’un temps de compilation plus grand. Si l’option existe pour la compilation sur iOS, une version experimentale de l’AOT pour Android a commencé à voir le jour et permet entre autres de démarrer les applications plus rapidement, et donne également la possibilité d’activer le LLVM.
ProGuard
C’est un outil développé dans le SDK Android qui permet entre autre de linker et d’obfusquer du code Java. A la manière du Linker pour le framework .Net, celui-ci va s’occuper des Google Play Services et ainsi réduire la taille du package.
Xamarin Forms — Xaml Compilé
Sur Xamarin Forms, sachez que l’activation du Xaml Compilé permet de réduire la taille du package (qui ne contiendra plus les .xaml) mais également d’augmenter légèrement les performances de l’application.
Pour terminer sur Xamarin
Avec ces techniques, vous serez alors en mesure de produire un package plus léger et donc de séduire un peu plus vos clients sur ce point là. De plus les performances à l’usage de votre application peuvent être améliorées. Maintenant c’est à vous de jouer.