La fusion d’une fonctionnalité apparemment anodine peut soudainement alourdir l’archive de plus de dix mégaoctets, sans qu’aucune image volumineuse ni nouvelle dépendance évidente n’apparaisse dans l’historique des commits. Si l’IPA n’est vérifié manuellement qu’avant la publication, le problème a généralement déjà gagné plusieurs branches. Une approche plus fiable consiste à conserver une référence de taille dans un environnement de build Mac cloud figé, puis à mesurer automatiquement l’App, l’exécutable principal et les frameworks dynamiques après chaque archivage. La fusion est bloquée dès qu’un seuil est dépassé.
Définir d’abord des mesures comparables
La « taille du package » recouvre au moins trois mesures distinctes, qui ne doivent pas être mélangées dans une même courbe.
| Indicateur | Élément mesuré | Usage principal |
|---|---|---|
| Taille déployée de l’App | Répertoire .app dans le .xcarchive |
Détecter l’augmentation des ressources, frameworks et fichiers de localisation |
| Taille de l’exécutable principal | Fichier Mach-O désigné par CFBundleExecutable |
Détecter les changements de code, de bibliothèques statiques et de symboles |
| Taille de l’IPA | Fichier compressé après export | Suivre l’évolution du package réellement téléchargé par les utilisateurs |
Le contrôle doit s’appuyer principalement sur les deux premières mesures. La taille de l’IPA dépend du taux de compression et de l’ordre des fichiers : de légères modifications dans un même ensemble de ressources peuvent donc amplifier ou réduire le résultat compressé. Les symboles de débogage se trouvent dans le répertoire dSYMs de l’archive et ne doivent pas être comptabilisés dans le package installé par l’utilisateur. Ils doivent néanmoins être archivés séparément afin de faciliter les analyses ultérieures.
Les écarts de taille ne sont interprétables que si les conditions de build sont identiques. Le chemin de Xcode, la configuration, la plateforme cible, la méthode d’export et les options de compilation doivent tous rester fixes.
Générer l’archive avec une commande stable
Commencez par résoudre les dépendances dans un répertoire de travail propre, puis générez une archive Release destinée à un appareil réel. Le nom du workspace et le Scheme sont transmis en paramètres de la tâche afin de ne pas figer les détails du projet dans le script.
set -euo pipefail
WORKSPACE="${WORKSPACE:?missing WORKSPACE}"
SCHEME="${SCHEME:?missing SCHEME}"
OUT="${OUT:-$PWD/build-size}"
ARCHIVE="$OUT/App.xcarchive"
rm -rf "$OUT"
mkdir -p "$OUT"
xcodebuild \
-workspace "$WORKSPACE" \
-scheme "$SCHEME" \
-configuration Release \
-destination 'generic/platform=iOS' \
-archivePath "$ARCHIVE" \
clean archive \
CODE_SIGNING_ALLOWED=NO
Si la phase d’archivage du projet doit exécuter des scripts liés à la signature, ne désactivez pas celle-ci de force. Utilisez plutôt la configuration contrôlée déjà prévue par le projet. L’objectif du contrôle est de reproduire fidèlement le build de production, et non de trouver une commande universelle pour tous les dépôts. Lors de la première intégration, vérifiez également que la configuration Release n’inclut pas par erreur des ressources de test, des bibliothèques de diagnostic ou des adresses de serveurs de développement.
Mesurer séparément l’App, l’exécutable et les frameworks
Le script ci-dessous recherche l’unique App présente dans l’archive, lit le nom de l’exécutable principal et produit un fichier TSV exploitable automatiquement. du -sk convient aux comparaisons continues de l’espace occupé par les répertoires, tandis que stat fournit la taille exacte de l’exécutable principal en octets.
set -euo pipefail
ARCHIVE="${1:?usage: measure.sh path/to/App.xcarchive}"
APP_ROOT="$ARCHIVE/Products/Applications"
APP_PATH="$(find "$APP_ROOT" -maxdepth 1 -type d -name '*.app' -print -quit)"
test -n "$APP_PATH"
EXECUTABLE="$(/usr/libexec/PlistBuddy \
-c 'Print :CFBundleExecutable' "$APP_PATH/Info.plist")"
printf "kind name bytes
"
APP_KB="$(du -sk "$APP_PATH" | awk '{print $1}')"
printf "app %s %s
" "$(basename "$APP_PATH")" "$((APP_KB * 1024))"
printf "executable %s %s
" "$EXECUTABLE" \
"$(stat -f '%z' "$APP_PATH/$EXECUTABLE")"
FRAMEWORKS="$APP_PATH/Frameworks"
if test -d "$FRAMEWORKS"; then
find "$FRAMEWORKS" -maxdepth 1 -type d -name '*.framework' -print0 |
while IFS= read -r -d '' item; do
kb="$(du -sk "$item" | awk '{print $1}')"
printf "framework %s %s
" "$(basename "$item")" "$((kb * 1024))"
done
fi
Le rapport doit être conservé comme artefact du build, au lieu de se limiter à l’affichage d’une taille totale. En cas de régression, les personnes chargées de la revue peuvent ainsi déterminer immédiatement si l’augmentation provient de l’exécutable principal, d’un framework particulier ou des ressources présentes dans l’ensemble du répertoire de l’App.
Détailler davantage les répertoires de ressources
Si la taille totale de l’App augmente alors que l’exécutable principal et les frameworks restent stables, exécutez séparément stat ou du sur Assets.car, les répertoires de localisation, les fichiers de données hors ligne et les ressources multimédias. Ne supprimez pas directement les fichiers qui semblent dupliqués : vérifiez d’abord s’ils sont générés par des targets différents, des règles de ressources à la demande ou le processus de localisation.
Réduire les faux positifs avec un double seuil
Un seuil uniquement exprimé en pourcentage rend les petits composants excessivement sensibles. À l’inverse, un seuil fixe en octets peut masquer l’augmentation continue d’une App volumineuse. L’incrément autorisé peut être défini ainsi :
allowed = max(8 MiB, baseline_app_bytes × 3%)
failed = current_app_bytes - baseline_app_bytes > allowed
Les valeurs 8 MiB et 3% ne sont que des paramètres initiaux d’intégration, pas une norme universelle. Commencez par enregistrer les variations de plusieurs archivages normaux, puis ajustez-les au projet. L’exécutable principal et chaque framework doivent disposer de seuils indépendants plus faibles, faute de quoi l’ajout d’une dépendance peut être masqué par la taille totale de l’App.
Le fichier de référence doit être révisé avec le code source, mais ne doit jamais être remplacé automatiquement par une tâche en échec. Le processus recommandé est le suivant : la tâche produit l’écart, le développeur en explique la cause, la personne chargée de la revue confirme que la modification répond au besoin, puis la référence est mise à jour dans le même changement. Cette procédure permet de distinguer une augmentation acceptée d’une simple réinitialisation des chiffres destinée à faire passer le contrôle.
Diagnostiquer les augmentations anormales courantes
Si l’exécutable principal grossit, commencez par examiner les dépendances statiques, les instanciations génériques, les liens dupliqués et les conditions de compilation. Si un framework grossit, vérifiez sa version et son mode d’intégration. Si les ressources grossissent, contrôlez les images sources, les polices, les fichiers audio et vidéo ainsi que les contenus de localisation dupliqués.
Évitez également quatre erreurs fréquentes :
- Comparer directement des résultats produits par des environnements Xcode différents.
- Mélanger des builds pour simulateur et des archives destinées à des appareils réels.
- Ne conserver que la taille totale, sans le détail des composants ni l’identifiant du commit.
- Augmenter automatiquement les seuils ou remplacer la référence après l’échec du contrôle.
Le rapport final doit contenir au minimum l’identifiant du commit, la configuration d’archivage, la taille totale de l’App, la taille de l’exécutable principal, les frameworks les plus volumineux, l’écart par rapport à la référence et le verdict du contrôle. Conservez le rapport même lorsque le contrôle réussit afin de repérer les augmentations lentes mais continues. En cas d’échec, conservez l’archive et les mesures détaillées pour les réexaminer dans le même environnement, plutôt que de dépendre d’un nouveau build local effectué par le développeur.
Questions fréquentes
Pourquoi ne pas comparer uniquement la taille finale de l’IPA ?
Un IPA est compressé et sa taille dépend du contenu des ressources, de l’ordre des fichiers et du comportement de l’outil d’archivage. Le bundle non compressé et l’exécutable principal sont de meilleurs indicateurs.
Comment choisir le seuil d’une régression de taille ?
Mesurez d’abord plusieurs versions normales, puis combinez une marge absolue et un pourcentage relatif. Les valeurs de 8 MiB et 3 % de l’exemple sont des points de départ à adapter à l’historique du projet.
Une mise à jour de dépendance justifie-t-elle automatiquement une nouvelle base ?
Non. Il faut identifier les symboles, ressources ou frameworks ajoutés et confirmer qu’ils sont attendus. La nouvelle base doit être validée et enregistrée avec la modification qui explique la hausse.
Placez votre prochaine compilation iOS sur MiniDebug M4.
M4, 16 Go de RAM et SSD de 256 Go inclus. Location à la journée, à la semaine, au mois ou au trimestre, avec cinq nœuds au choix : Singapour, Tokyo, Séoul, Hong Kong et côte Est des États-Unis. La disponibilité réelle est indiquée en temps réel dans la console.