Réduire la taille de votre application

Les utilisateurs évitent souvent de télécharger des applications qui paraissent trop volumineuses, en particulier sur les marchés émergents où les appareils se connectent à des réseaux 2G et 3G instables ou qui utilisent des forfaits avec des limites de données. Cette page explique comment réduire la taille de téléchargement de votre application afin de permettre à davantage d'utilisateurs de la télécharger.

Importer votre application avec Android App Bundle

Importez votre application en tant qu'Android App Bundle pour enregistrer immédiatement sa taille lorsque vous la publiez sur Google Play. Android App Bundle est un format d'importation qui inclut l'ensemble du code compilé et les ressources de votre application, mais reporte la génération des APK et leur signature sur Google Play.

Le modèle de diffusion d'application de Google Play utilise ensuite votre app bundle pour générer et diffuser des APK optimisés pour la configuration d'appareil de chaque utilisateur, afin qu'ils téléchargent uniquement le code et les ressources dont ils ont besoin pour exécuter votre application. Vous n'avez pas besoin de créer, de signer ni de gérer plusieurs APK pour prendre en charge différents appareils, et les utilisateurs bénéficient de téléchargements plus petits et plus optimisés.

Google Play applique une limite de taille de téléchargement compressée de 200 Mo pour les applications publiées avec des app bundles. Des tailles plus importantes sont possibles avec Play Feature Delivery et Play Asset Delivery, mais augmenter la taille de votre application peut avoir un impact négatif sur la réussite des installations et augmenter les désinstallations. Nous vous recommandons donc d'appliquer les consignes décrites sur cette page pour réduire autant que possible la taille de téléchargement de votre application.

Comprendre la structure de l'APK

Avant de réduire la taille de votre application, il est utile de comprendre la structure de son APK. Un fichier APK se compose d'une archive ZIP contenant tous les fichiers qui composent votre application. Ces fichiers incluent des fichiers de classe Java, des fichiers de ressources et un fichier contenant des ressources compilées.

Un APK contient les répertoires suivants :

  • META-INF/ : contient les fichiers de signature CERT.SF et CERT.RSA, ainsi que le fichier manifeste MANIFEST.MF.
  • assets/ : contient les composants de l'application, que celle-ci peut récupérer à l'aide d'un objet AssetManager.
  • res/ : contient les ressources qui ne sont pas compilées dans resources.arsc.
  • lib/ : contient le code compilé spécifique à la couche logicielle d'un outil de traitement. Ce répertoire contient un sous-répertoire pour chaque type de plate-forme, tel que armeabi, armeabi-v7a, arm64-v8a, x86, x86_64 et mips.

Un APK contient également les fichiers suivants. Seul AndroidManifest.xml est obligatoire :

  • resources.arsc : contient les ressources compilées. Ce fichier inclut le contenu XML de toutes les configurations du dossier res/values/. L'outil d'empaquetage extrait ce contenu XML, le compile au format binaire, puis l'archive. Le contenu inclut des chaînes et des styles de langage, ainsi que des chemins d'accès à du contenu qui n'est pas directement inclus dans le fichier resources.arsc, comme des fichiers de mise en page et des images.
  • classes.dex : contient les classes compilées au format de fichier DEX interprété par la machine virtuelle Dalvik ou ART.
  • AndroidManifest.xml : contient le fichier manifeste Android principal. Ce fichier liste le nom, la version, les droits d'accès et les fichiers de bibliothèque référencés de l'application. Le fichier utilise le format XML binaire d'Android.

Réduire le nombre et la taille des ressources

La taille de votre APK a des répercussions sur la vitesse de chargement de votre application, la quantité de mémoire qu'il utilise et la consommation d'énergie. Vous pouvez réduire la taille de votre APK en diminuant le nombre et la taille des ressources qu'il contient. Vous pouvez par exemple supprimer les ressources que votre application n'utilise plus et utiliser des objets Drawable évolutifs à la place des fichiers image. Cette section décrit ces méthodes et d'autres façons de réduire les ressources dans votre application afin de réduire la taille globale de votre APK.

Supprimer les ressources inutilisées

L'outil lint, un analyseur de code statique inclus dans Android Studio, détecte les ressources de votre dossier res/ non référencées par votre code. Lorsque l'outil lint détecte une ressource potentiellement inutilisée dans votre projet, il affiche un message semblable à l'exemple suivant.

res/layout/preferences.xml: Warning: The resource R.layout.preferences appears
    to be unused [UnusedResources]

Les bibliothèques que vous ajoutez à votre code peuvent inclure des ressources inutilisées. Gradle peut automatiquement supprimer des ressources en votre nom si vous activez shrinkResources dans le fichier build.gradle.kts de votre application.

Kotlin

android {
    // Other settings.

    buildTypes {
        getByName("release") {
            minifyEnabled = true
            shrinkResources = true
            proguardFiles(getDefaultProguardFile('proguard-android.txt'), "proguard-rules.pro")
        }
    }
}

Groovy

android {
    // Other settings.

    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

Pour utiliser shrinkResources, activez la minification de code. Au cours du processus de compilation, R8 supprime d'abord le code inutilisé. Le plug-in Android Gradle supprime ensuite les ressources inutilisées.

Pour en savoir plus sur la minification du code et des ressources et pour découvrir d'autres façons dont Android Studio réduit la taille de l'APK, consultez la section Réduire, obscurcir et optimiser votre application.

Dans le plug-in Android Gradle 7.0 et versions ultérieures, vous pouvez déclarer les configurations compatibles avec votre application. Gradle transmet ces informations au système de compilation à l'aide des types de données resourceConfigurations et de l'option defaultConfig. Le système de compilation empêche ensuite l'affichage des ressources d'autres configurations non compatibles dans l'APK, ce qui réduit la taille de celui-ci. Pour en savoir plus sur cette fonctionnalité, consultez la section Supprimer les autres ressources non utilisées.

Minimiser l'utilisation des ressources des bibliothèques

Lorsque vous développez une application Android, vous utilisez généralement des bibliothèques externes pour améliorer la facilité d'utilisation et la polyvalence de votre application. Par exemple, vous pouvez faire référence à AndroidX pour améliorer l'expérience utilisateur sur les anciens appareils, ou utiliser les services Google Play pour récupérer les traductions automatiques de texte dans votre application.

Si une bibliothèque est conçue pour un serveur ou un ordinateur, elle peut inclure de nombreux objets et méthodes dont votre application n'a pas besoin. Pour n'inclure que les parties de la bibliothèque dont votre application a besoin, vous pouvez modifier les fichiers de la bibliothèque si la licence vous le permet. Vous pouvez également utiliser une autre bibliothèque adaptée aux appareils mobiles pour ajouter des fonctionnalités spécifiques à votre application.

Décodage des images animées en mode natif

Sous Android 12 (niveau 31 d'API), l'API ImageDecoder NDK a été étendue pour décoder tous les frames et toutes les données de codes temporels qui utilisent le GIF et les formats de fichiers WebP animés.

Utilisez ImageDecoder au lieu de bibliothèques tierces pour encore diminuer la taille de l'APK et bénéficier de futures mises à jour liées à la sécurité et aux performances.

Pour en savoir plus sur l'API ImageDecoder, reportez-vous à API reference et à l'exemple sur GitHub.

N'accepter que certaines densités

Android est compatible avec différentes densités d'écran, par exemple :

  • ldpi
  • mdpi
  • tvdpi
  • hdpi
  • xhdpi
  • xxhdpi
  • xxxhdpi

Bien qu'Android soit compatible avec toutes ces densités, il est inutile d'exporter vos éléments rastérisés vers chaque densité.

Si vous savez que seul un faible pourcentage de vos utilisateurs possède des appareils avec des densités spécifiques, envisagez de les regrouper dans votre application. Si vous n'incluez pas de ressources pour une densité d'écran spécifique, Android adapte automatiquement les ressources existantes initialement conçues pour d'autres densités d'écran.

Si votre application n'a besoin que d'images mises à l'échelle, vous pouvez économiser encore plus d'espace en utilisant une seule variante d'image dans drawable-nodpi/. Nous vous recommandons d'inclure au moins une variante d'image xxhdpi dans votre application.

Pour en savoir plus sur les densités d'écran, consultez la section Tailles et densités d'écran.

Utiliser des objets drawable

Certaines images ne nécessitent pas de ressource d'image statique. À la place, le framework peut dessiner l'image de manière dynamique au moment de l'exécution. Les objets Drawable (<shape> en XML) peuvent occuper un espace très réduit dans votre APK. En outre, les objets XML Drawable produisent des images monochromes conformes aux consignes de Material Design.

Réutiliser des ressources

Vous pouvez inclure une ressource distincte pour les variantes d'une image, comme des versions teintées, ombrées ou pivotées de la même image. Toutefois, nous vous recommandons de réutiliser le même ensemble de ressources et de les personnaliser selon vos besoins au moment de l'exécution.

Android fournit plusieurs utilitaires permettant de modifier la couleur d'un composant à l'aide des attributs android:tint et tintMode.

Vous pouvez également ignorer les ressources identiques à d'autres ressources avec un effet de rotation ajouté. L'extrait de code suivant fournit un exemple de transformation d'un avis "J'aime" en "Je n'aime pas" en le faisant pivoter à 180 degrés au milieu de l'image :

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_thumb_up"
    android:pivotX="50%"
    android:pivotY="50%"
    android:fromDegrees="180" />

Afficher à partir du code

Vous pouvez également réduire la taille de votre APK en affichant systématiquement vos images. Le rendu systématique libère de l'espace, car vous ne stockez plus de fichier image dans votre APK.

Maîtriser les fichiers PNG

L'outil aapt peut optimiser les ressources d'image placées dans res/drawable/ avec une compression sans perte pendant le processus de compilation. Par exemple, l'outil aapt peut convertir un fichier PNG en couleurs réelles qui ne requiert pas plus de 256 couleurs en fichier PNG 8 bits avec une palette de couleurs. Cela donne une image de qualité égale, mais un espace mémoire utilisé plus petit.

aapt présente les limites suivantes :

  • L'outil aapt ne réduit pas les fichiers PNG contenus dans le dossier asset/.
  • Les fichiers image doivent utiliser 256 couleurs ou moins pour que l'outil aapt les optimise.
  • L'outil aapt peut gonfler les fichiers PNG déjà compressés. Pour éviter cela, vous pouvez utiliser l'indicateur isCrunchPngs afin de désactiver ce processus pour les fichiers PNG :
  • Kotlin

        buildTypes.all { isCrunchPngs = false }
        

    Groovy

        buildTypes.all { isCrunchPngs = false }
        

Compresser les fichiers PNG et JPEG

Vous pouvez réduire la taille des fichiers PNG sans perdre la qualité de l'image à l'aide d'outils tels que pngcrush, pngquant ou zopflipng. Tous ces outils peuvent réduire la taille du fichier PNG tout en préservant la qualité de l'image perçue.

L'outil pngcrush est particulièrement efficace. Il effectue une itération sur les filtres PNG et les paramètres zlib (Deflate), en utilisant chaque combinaison de filtres et de paramètres pour compresser l'image. Il choisit ensuite la configuration qui génère la plus petite sortie compressée.

Pour compresser les fichiers JPEG, vous pouvez utiliser des outils tels que packJPG et guetzli.

Utiliser le format de fichier WebP

Au lieu d'utiliser des fichiers PNG ou JPEG, vous pouvez également utiliser le format de fichier WebP pour vos images. Le format WebP offre une compression avec pertes et une transparence, comme JPG et PNG, et peut fournir une meilleure compression qu'avec JPEG ou PNG.

Vous pouvez convertir des images BMP, JPG, PNG ou GIF statiques au format WebP à l'aide d'Android Studio. Pour en savoir plus, consultez la section Créer des images WebP.

Utiliser des graphiques vectoriels

Vous pouvez utiliser des images vectorielles pour créer des icônes indépendantes de la résolution et d'autres contenus multimédias évolutifs. Vous pouvez utiliser ces images pour réduire considérablement l'empreinte de votre APK. Dans Android, les images vectorielles sont représentées par des objets VectorDrawable. Avec un objet VectorDrawable, un fichier de 100 octets peut générer une image nette de la taille de l'écran.

Toutefois, il faut beaucoup de temps au système pour afficher chaque objet VectorDrawable. L'affichage d'images volumineuses prend encore plus de temps. Nous vous recommandons donc de n'utiliser ces graphiques vectoriels que pour afficher de petites images.

Pour en savoir plus sur l'utilisation d'objets VectorDrawable, consultez la section Drawables.

Utiliser des graphiques vectoriels pour les images animées

N'utilisez pas AnimationDrawable pour créer des animations frame par frame, car cela nécessite d'inclure un fichier bitmap distinct pour chaque frame de l'animation, ce qui augmente considérablement la taille de votre APK.

Utilisez plutôt AnimatedVectorDrawableCompat pour créer des drawables vectoriels animés.

Réduire le code natif et Java

Vous pouvez utiliser les méthodes suivantes pour réduire la taille du code Java et du codebase natif de votre application.

Supprimer le code généré inutilement

Veillez à bien comprendre l'empreinte de tout code généré automatiquement. Par exemple, de nombreux outils de tampon de protocole génèrent un nombre excessif de méthodes et de classes, ce qui peut doubler ou tripler la taille de votre application.

Éviter les énumérations

Une seule énumération peut ajouter environ 1 à 1,4 Ko au fichier classes.dex de votre application. Ces ajouts peuvent rapidement s'accumuler pour des systèmes complexes ou des bibliothèques partagées. Si possible, utilisez l'annotation @IntDef et la minification de code pour supprimer les énumérations et les convertir en entiers. Cette conversion de type préserve tous les avantages liés à la sûreté du typage des énumérations.

Réduire la taille des binaires natifs

Si votre application utilise du code natif et du code NDK Android, vous pouvez également réduire la taille de la version finale de votre application en optimisant votre code. Deux techniques utiles permettent de supprimer les symboles de débogage et de ne pas extraire les bibliothèques natives.

Supprimer les symboles de débogage

L'utilisation de symboles de débogage est logique si votre application est en cours de développement et nécessite toujours un débogage. Utilisez l'outil arm-eabi-strip fourni dans le NDK Android pour supprimer les symboles de débogage inutiles des bibliothèques natives. Vous pouvez ensuite compiler votre build.

Éviter d'extraire des bibliothèques natives

Lorsque vous compilez la version de votre application, empaquetez les fichiers .so non compressés dans l'APK en définissant useLegacyPackaging sur false dans le fichier build.gradle.kts de votre application. La désactivation de cet indicateur empêche PackageManager de copier les fichiers .so de l'APK vers le système de fichiers lors de l'installation. Cette méthode réduit la taille des mises à jour de votre application.

Gérer plusieurs APK légers

Votre APK peut comporter du contenu que les utilisateurs téléchargent sans jamais l'utiliser, comme des langues supplémentaires ou des ressources par densité d'écran. Pour que vos utilisateurs bénéficient d'un téléchargement minimal, importez votre application sur Google Play à l'aide d'Android App Bundle. L'importation des app bundles permet à Google Play de générer et de diffuser des APK optimisés pour la configuration de l'appareil de chaque utilisateur, afin qu'ils ne téléchargent que le code et les ressources nécessaires à l'exécution de votre application. Vous n'avez plus besoin de créer, de signer ni de gérer plusieurs APK pour prendre en charge différents appareils, et les utilisateurs bénéficient de téléchargements plus petits et mieux optimisés.

Si vous ne publiez pas votre application sur Google Play, vous pouvez la segmenter en plusieurs fichiers APK, qui se distinguent par des facteurs tels que la taille de l'écran ou la compatibilité avec la texture GPU.

Lorsqu'un utilisateur télécharge votre application, son appareil reçoit l'APK approprié en fonction des fonctionnalités et des paramètres de l'appareil. Ainsi, les appareils ne reçoivent pas les composants dont ils n'ont pas besoin. Par exemple, si un utilisateur possède un appareil hdpi, il n'a pas besoin des ressources xxxhdpi que vous pouvez inclure pour les appareils à plus grande densité d'affichage.

Pour en savoir plus, consultez la section Créer plusieurs fichiers APK et Prendre en charge plusieurs fichiers APK.