Як виміряти та зменшити розмір iOS-застосунку за допомогою Xcode і App Store Connect
Public- 13 Nov, 2026

iOS-застосунки зазвичай ростуть з кожним релізом: додаються нові SDK, зображення у вищій роздільній здатності та офлайн-контент. Завантаження триває довше, а на пристрої зайнято більше місця. Оптимізацію починають із вимірювань, бо головне джерело ваги в кожного застосунку своє: в одних це ресурси, в інших скомпільований код або вбудовані залежності. «Розмір застосунку» теж не можна звести до одного числа. Розмір завантаження, розмір встановлення та місце, зайняте після використання, перетинаються, але не замінюють одне одного. Тому в PR, бенчмарку чи звіті команді вказуйте, яка метрика змінилася і де її вимірювали. Якщо необов'язковий контент завантажується пізніше, початкові завантаження та встановлення стають меншими, але після завантаження цей контент однаково опиняється на пристрої. Background Assets, зокрема обов'язкові пакети та заздалегідь завантажуваний контент, можуть надійти навіть до першого запуску. Їх потрібно враховувати окремо й порівнювати за однакового стану завантаження.
Користувач бачить ці цифри у двох місцях. На сторінці застосунку в App Store поле «Інформація → Розмір» показує розмір встановлення. Якщо застосунок використовує обов'язкові пакети ресурсів на серверах Apple, там може бути значення «До …» з урахуванням цього контенту. У розділі «Сховище iPhone» окремо вказано розмір застосунку та «Документи й дані», які накопичуються в міру завантажень і використання. Локальні файли APP, XCARCHIVE та IPA допомагають у діагностиці, але не збігаються з тим, що доставляє App Store: в архівах бувають налагоджувальні символи, а універсальний IPA містить ресурси для різних пристроїв. Щоб оцінити розмір для конкретних пристроїв, експортуйте Release-архів командою xcodebuild -exportArchive з параметрами -archivePath, -exportPath та -exportOptionsPlist. За ручного підписування в plist також потрібні signingStyle=manual, teamID і зіставлення provisioningProfiles для кожного застосунку або розширення.

У папці експорту з'явиться App Thinning Size Report.txt. У ньому перелічено варіанти з описом пристрою та ОС і значеннями на кшталт «112 MB compressed, 260 MB uncompressed». Стиснутий розмір - це оцінка завантаження, нестиснутий - оцінка встановлення. Щоб дослідити бандл, виберіть проріджений IPA за описом варіанта, а не за назвою файлу: експорт може містити й універсальний IPA. Розпакуйте його через ditto -x -k у новий каталог, створений mktemp, і знайдіть .app у папці Payload. Для App Store і TestFlight проріджування здебільшого працює саме, але його варто перевірити. Якщо ресурси для окремих пристроїв потрапляють в усі варіанти, перевірте налаштування каталогів ресурсів і окремі файли. Під час порівняння не змінюйте конфігурацію збирання, версію Xcode, спосіб підпису, спосіб експорту та опис варіанта, а потім повторіть порівняння за обробленими значеннями App Store Connect. Це теж лише оцінки: Apple може додати DRM і перестиснути файли, а розміри в TestFlight можуть відрізнятися від App Store.
Діагностику починають з опису всього прорідженого бандла: головний виконуваний файл, Frameworks, PlugIns, каталоги ресурсів і окремі ресурси, локалізації, медіа, бази даних і ML-моделі. Команда find зі stat, sort -n і tail -30 покаже найбільші файли, але це логічні нестиснуті розміри, тобто лише підказка. Якщо важливий бінарник, увімкніть у Build Settings параметр Write Link Map File (LD_GENERATE_MAP_FILE), зберіть проєкт і розберіть .txt у DerivedData. Згрупуйте розміри з розділу # Symbols за індексом файлу, а індекси зіставте з розділом # Object files. Так видно важкий згенерований код, статичні бібліотеки, шаблони C++ і сторонні SDK. Суми за символами показують, кому належить вага, але не дають повного обліку: заголовки, вирівнювання, підписи та дані компонувальника туди не входять. Вбудовування, оптимізація всього модуля і LTO розмивають належність коду. Символи, видалені як мертвий код, виключайте, а карту будуйте для кожної цілі збирання та архітектури.

Порядок роботи покажемо на умовному прикладі з вигаданими числами: змінюємо щось одне, перезбираємо і знову отримуємо звіт для того самого варіанта. Застосунок із великою кількістю ресурсів важить 112 МБ у стиснутому вигляді та 260 МБ у нестиснутому. Оцінка зменшується на 31 МБ (близько 28%) і 58 МБ (близько 22%), а App Store Connect показує 80 МБ завантаження і 200 МБ встановлення. Економія не переноситься один до одного: втручаються компіляція, нарізання, стиснення, вирівнювання та підпис. Навчання, перенесене на віддалену доставку, відкладається, а не видаляється. Після його завантаження зайняте місце знову зростає приблизно на 32 МБ, і на диску можуть одночасно лежати архів і розпаковані файли. Тому перевіряйте роботу без мережі, повторні спроби, очищення та повторне завантаження, а дельта-оновлення вимірюйте окремо.
Ресурси часто важать більше за код. Вбудовані зображення тримайте в .xcassets, щоб app thinning підбирав ресурси під кожен пристрій. Кількість пікселів має відповідати розміру на екрані: іконці 24 × 24 пункти потрібно 48 × 48 пікселів для 2x і 72 × 72 для 3x, а зменшувати її слід до імпорту. Універсальну графіку використовуйте спільну, варіанти під пристрої або колірне охоплення додавайте лише за потреби й не дублюйте набори зображень. Після перенесення завантажуйте зображення за назвою, наприклад UIImage(named: "toolbar_search"), а залишені окремі копії приберіть із Copy Bundle Resources. Результат підтвердьте, порівнявши звіти для того самого варіанта до і після. Для іконок краще брати системні SF Symbols, якщо це дозволяють дизайн і мінімальна версія ОС.