- PVSM.RU - https://www.pvsm.ru -
В некоторых случаях необходимо работать над снижением размера сборки для Андроид. Например, установка тяжеловесных APK для пользователей мобильного интернета может влететь в копеечку. Превышение размера APK в 50 Мб в Google Play выливается в дополнительные трудности при аплоаде.
В компании Intellijoy мы разрабатывали под Андроид на Unity [1] 2D-игру, которая изобилует картинками (большинство с областями прозрачности) и разнообразными звуками, и столкнулись с проблемой размера APK. Забегая вперед скажу, что решив ее и снизив вес в 1,5 раза, мы получили в 1,5 раза больше скачиваний. Заставляет задуматься, не правда ли?
Пытаясь побороть проблему приложений-тяжеловесов, мы обратились к замечательной документации [2] от Unity. Выяснилось, что там данная тема обсуждается лишь вскользь. Упоминается, какие именно аспекты влияют на размер сборки и как воздействовать на эти аспекты, чтобы сделать APK меньше, а также приведено немного конкретики по поводу настроек импорта изображений.
Другую полезную информацию по данному вопросу в интернете мы практически не нашли. Потому провели небольшое исследование, результатами которого спешим с вами поделиться.
Итак, согласно документации, на размер сборки влияет:
С мешами и импортированными анимационными клипами мы не работали, потому начнем с ассетов.
Проанализируем, какой вклад в размер АРК вносят изображения в формате PNG и JPG.
Для PNG этот вклад зависит от двух «переменных»:
Мы сохранили 3 картинки в Photoshop с настройками: Compression->Smallest/Slow, Intrelaced: No. Картинка PNG размером 295 Кбайт заняла в сборке места 236 Кбайт. Картинка 612 Кбайт заняла 480 Кбайт. Картинка 21,2 Кбайт заняла 23 Кбайт (естественно, при одинаковых настройках импорта). Пропроциональность очевидна.
Далее мы сохранили первую картинку в Photoshop с настройками: Compression->None/Fast, Intrelaced: Yes. Получили файл размером 9000 Кбайт, однако в сборку он добавил те же 236 Кбайт.
Это подтверждает слова из документации, о том, что Unity перекодирует все ассеты во внутренний формат. Очевидно, он приблизительно соответствует формату PNG, сохранённому в фотошопе с настройками: Compression->Smallest/Slow, Intrelaced: No. И Unity перекодирует все PNG в этот формат, независимо от начального формата файла.
Опыты однозначно показали, что изображения JPG вносят вклад в размер сборки пропорционально своему размеру. Пока не совсем понятно, как ведёт себя Unity в случае, если ассет находится в формате JPG. Мы сохранили ту же самую (первую) картику в JPG и получили очень маленький файл на файловой системе (75 Кбайт). Однако в сборке он занял непомерных 767 Кбайт (*).
Мы проводили эксперимент на большом количестве разных картинок, здесь я привожу лишь малую часть исследований. В других экспериментах нам наоборот удавалось снизить общий размер сборки конвертированием всех файлов из PNG в JPG.
Причин этого явления выявить пока не удалось.
Скорее всего, снова имеет место внутренний формат Unity, однако точные принципы взаимодействия колдовского механизма Unity с ассетами JPG выяснить пока не удалось.
Еще один способ работы с JPG будет описан ниже.
Выводы
Настройки импорта влияют на размер сборки совершенно так, как это описано в доке (чем качественнее картинка, тем больший её вклад в размер сборки). Здесь скрытых особенностей не выявлено. (С другими форматами изображений эксперименты пока не проводились.)
Для звуков значение имеют две настройки импорта: Audio Format и ForceToMono.
Файлы в формате WAV занимают больше места в сборке, чем файлы в формате MP3 (вклад в размер сборки приблизительно равен размеру файла). Стерео WAV файл займёт меньше места, если выставить ForceToMono = true. Точно такого же эффекта можно достичь, если конвертировать файл в «моно» ещё до импорта (тогда ForceToMono не будет доступна в инспекторе).
Однако если для файла WAV установить настройку импорта AudioFormat = Compressed, то в сборке он займёт места столько же, сколько и соответствующий MP3 файл высшего качества (Audacity: variable bitrate, 220-260 kbps). То есть Unity самостоятельно кодирует звук в формат MP3.
Для файлов в одинаковом формате действует принцип прямо пропорционального вклада в размер сборки.
Остальные настройки импорта на размер сборки никак не влияют. Они влияют на количество места, занимаемое звуком в RAM.
Таким образом, совет: для снижения нагрузки на ОЗУ
* избегать больших областей прозрачности в изображениях;
* не формировать атласы с большими участками прозрачности, особенно в NGUI.
(Но это мы отвлеклись от основной темы.)
После выполнения каждого пункта желательно проверять полученный эффект. Поскольку в поведении Unity всё же есть доля магии.
Документ [2] приводит список обязательно включаемых в сборку dll и призывает минимизировать количество дополнительных dll (особенно тяжёлых). В частности, по возможности не использовать System.dll (добавляет к APK 2 Мбайт). Однако даже если мы будем избегать ссылок на методы из этой библиотеки, System.dll всё равно (по состоянию на Unity 4.5.5) включается в сборку, так как её подтягивает обязательная Mono.Security.dll. Потому, получается, что официальная документация Unity в этом месте не совсем релевантна.
А вот использования других (необязательных) dll желательно избегать во имя снижения размера сборки.
На сегодня у нас всё. Спасибо за внимание!
(Просьба рассматривать данный материал как более-менее систематизированные результаты исследования, а не как универсальное руководство к действию. Буду очень рад комментариям, замечаниям, конструктивной критике, возражениям, предложениям, дополнениям. И, конечно, несказанно рад буду узнать, какие приёмы применяют коллеги из других компаний для решения обсуждаемого вопроса.)
Автор: Denvery
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/android/83272
Ссылки в тексте:
[1] Unity: http://unity3d.com/
[2] документации: http://docs.unity3d.com/Manual/ReducingFilesize.html
[3] Источник: http://habrahabr.ru/post/250873/
Нажмите здесь для печати.