Réduire la taille de votre application

Restez organisé à l'aide des collections Enregistrez et classez les contenus selon vos préférences.

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 souvent instables ou qui utilisent des forfaits à la carte. 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

Le moyen le plus simple d'économiser immédiatement de l'espace au moment de publier sur Google Play consiste à importer votre application en tant qu'Android App Bundle, un nouveau format d'importation qui inclut le code compilé et les ressources de votre application, mais reporte la génération des APK et leur signature sur Google Play.

Le nouveau 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 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 plus optimisés.

N'oubliez pas que nous appliquons les consignes décrites ci-dessus pour réduire autant que possible la taille de téléchargement de votre application, car Google Play applique une limite de taille de téléchargement compressée de 150 Mo ou moins pour les applications publiées avec des app bundles.

Pour les applications que vous publiez sur Google Play en important des APK signés, les téléchargements compressés sont limités à 100 Mo.

Comprendre la structure de l'APK

Avant de voir comment 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 plateforme, tel que armeabi, armeabi-v7a, arm64-v8a, x86, x86_64 et mips.

Un APK contient également les fichiers suivants. Parmi eux, 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/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. L'un des moyens les plus simples pour réduire la taille de votre APK consiste à réduire 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, ainsi que plusieurs autres vous permettant 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]

Remarque : L'outil lint n'analyse pas le dossier assets/, les éléments référencés par réflexion ou les fichiers de bibliothèque que vous avez associés à votre application. De plus, il ne supprime pas les ressources ; il se contente de vous avertir de leur présence.

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 de votre application.

Groovy

android {
    // Other settings

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

Kotlin

android {
    // Other settings

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

Pour utiliser shrinkResources, vous devez également activer 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 vous aide à réduire la taille de l'APK, consultez Réduire, obscurcir et optimiser votre application.

Dans la version 0.7 ou supérieure du plug-in Android Gradle, 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 resConfig et resConfigs 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 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 à la Bibliothèque Android Support 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 a été 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.

Remarque : La minification de code permet de supprimer une partie du code inutile d'une bibliothèque, mais il est possible qu'il ne puisse pas supprimer certaines dépendances internes volumineuses.

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. À son lancement sous Android 11, cette API ne décodait que la première image à partir d'animations dans ces formats.

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, reportez-vous à API reference et à l'exemple sur GitHub.

N'accepter que certaines densités

Android est compatible avec une gamme très variée d'appareils, qui incluent différentes densités d'écran. Dans Android version 4.4 (niveau 19 d'API) ou ultérieure, le framework accepte différentes densités : ldpi, mdpi, tvdpi, hdpi, xhdpi, xxhdpi et xxxhdpi Bien qu'Android soit compatible avec toutes, 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 chaque application.

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

Utiliser des objets drawable

Certaines images n'ont pas besoin de ressource d'image statique : 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. Nous vous recommandons toutefois de réutiliser le même ensemble de ressources en les personnalisant 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 sur Android version 5.0 (niveau 21 d'API) ou supérieure. Pour les versions antérieures de la plateforme, utilisez la classe ColorFilter.

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îtrisez 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.

N'oubliez pas que l'élément 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 :

Groovy

buildTypes.all { isCrunchPngs = false }

Kotlin

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.

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

Si vous ciblez Android version 3.2 (niveau 13 d'API) ou ultérieure, vous pouvez également utiliser le format de fichier WebP pour vos images plutôt que des fichiers PNG ou JPEG. Le format WebP offre une compression avec pertes (comme JPEG) ainsi qu'une transparence (comme PNG), mais peut offrir 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 Créer des images WebP à l'aide d'Android Studio.

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. Ces images peuvent 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 Utiliser des ressources drawable.

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

Il existe plusieurs méthodes 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 version de compilation.

Éviter d'extraire des bibliothèques natives

Lorsque vous compilez la version finale de votre application, empaquetez les fichiers .so non compressés dans l'APK en vous assurant que useLegacyPackaging est défini sur false dans le fichier build.gradle de votre application. La désactivation de cet indicateur empêche PackageManager de copier les fichiers .so du fichier APK dans le système de fichiers lors de l'installation et permet également de réduire 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, nous vous conseillons d'importer votre application sur Google Play au format 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 et de gérer plusieurs APK pour prendre en charge différents appareils, et les utilisateurs bénéficient de téléchargements réduits 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 Configurer la division du fichier APK et Gérer plusieurs fichiers APK.