Главное Авторские колонки Вакансии Образование
Выбор редакции:
1 943 5 В избр. Сохранено
Авторизуйтесь
Вход с паролем

Как MnCreator оптимизирует размер приложений

Проблема: приложение "Сказки внутри" студии "Друг За Друга" весит много: больше 130 мегабайт. Рассказ о том, как я уменьшил это число почти в 2 раза.
Мнение автора может не совпадать с мнением редакции

Зачем это нужно?

AppStore не позволяет качать приложения больше 100 мегабайт через сотовую сеть без Wi-Fi, отсюда теряется часть пользователей. Плюс загрузка приложения, сцен и т.п. происходит долго.

Исходные материалы:

  • Графика для приложения: 1656 файлов общим весом в 56.7 мб
  • Звук: 115 файлов, 59.7 мб
  • Скриншоты сцен для навигации и иконка приложения: 43 файла, 11.5 мб (из них 3 мб - только иконка).

Был написан специальный анализатор исходных материалов внутри самого конструктора MnCreator, который работает по очень простому принципу:

  1. Собираем все исходные материалы со всех сцен, компонентов, объектов и так далее. То есть у нас на выходе есть полный список всех файлов, которые используются в проекте (считается, что плагины должны вернуть все файлы, которые они используют).
  2. Прогоняем каждый файл по определенным критериям (о них - чуть ниже) и, если он попадает под оптимизацию, предлагаем пользователю сделать это.

Критерии

Всего критериев было 5 (4 основных + 1 через дополнительный компонент, но на самом деле критериев, которые реально дают эффект только 3). Поехали:

1. Очевидно, смотрим на файлы, которые не используются. MnCreator при сборке проекта не заморачиваться забирать только используемые файлы, а архивирует сразу всю папку проекта. С одной стороны это нехорошо, потому что кто знает сколько там мусора. С другой стороны, подробный анализ файлов занимает от 2 до 10 минут, и никто не хочет ждать столько времени при компиляции проекта (учитывая что без этого этапа компиляция занимает не больше 30 секунд).

2. Дальше смотрим на одинаковые файлы. Такое случается, когда на нескольких сценах используются одни и те же элементы интерфейса или наборы объектов. Как правило, дизайнеры/аниматоры их просто копируют в нужную папку и всё. Чтобы понять какие файлы одинаковые, берется их контент, считается MD5-сумма и сравнивается с суммами других файлов. У кого совпали - те файлы одинаковые, и значит из них можно выбрать только 1, а остальные удалить. Реальной оптимизации размера, как правило, не получается, потому что обычно это очень маленькие файлы. Но ускоряется загрузка сцена за счет кэширования этих десятков файлов.

3. Хм, а давайте на всякий случай проверим файлы, которые не существуют? То есть плагин или компонент хочет использовать этот файл, но реально в папке проекта его нет. Такое случается, если автор приложения зачем-то залез и руками удалил, переместил или переименовал файл. На самом деле движок просто не сможет загрузить эту сцену вообще, и этот пункт никак не влияет на оптимизацию, а является скорее обязательным критерием для проверки перед компиляцией проекта.

Варианты что делать с самими файлами исчерпаны. Теперь начинаем думать что делать с контентом файлов:

4. В случае с PNG изображениями они иногда бывают без прозрачного слоя. Вообще. Такие файлы можно перегнать в JPG и освободить драгоценные мегабайты. Такой случай нередок, обычно это происходит из-за того, что файлы в проект экспортируются из Adobe Photoshop через какой-нибудь automate -> batch, который экспортирует каждый слой в отдельный PNG-файл. Анализ простой: загружаем изображение, рисуем на canvas, смотрим на 4е байты в getImageData (отвечают как раз за прозрачный слой) и если где-то они не 255, то значит прозрачность есть. Изначально была мысль рисовать на канвас меньшего размера, но смысла нет - и так быстро работает.

5. И последний, самый навороченный вариант, это пережимать каким-либо способом оставшиеся файлы.

Как пережимать?

Первая мысль - погуглить. Сразу нашлась толпа онлайн-сервисов по пережатию изображений, многие даже с API. Вторая мысль - надо интегрироваться, мозг начинает судорожно придумывать схему взаимодействия: чтобы не палить API-ключ нужно закачивать файлы сначала на облако MnCreator, потом оттуда уже на сервис, получать оптимизированную версию, отдавать обратно клиенту. А чтобы избежать повторных оптимизаций одного и того же файла, нужно кэшировать оригинальную и пережатую версию. В общем, не тривиальненько, зато хороший кейс для дополнительной монетизации.

Я уж было сел писать всё это дело, но посмотрел на цены. Взять тот же tinypng.com: цена за файл - до 0.009$. Казалось бы, немного. Чтобы быть хоть как-то в плюсе, добавим 10%, цена получится 0.01$. Умножаем на 1600 файлов, получаем 16$, которые пользователь должен будеть отдать за сжатие подобного приложения. Оно, конечно большое, и действие это разовое, но цена всё равно кусается. С другими сервисами примерно такая же история.

Ок, продолжаем копать. Выяснилось, что tinypng - это просто "обёртка" с веб-мордой над утилиткой pngquant. И есть много npm-пакетов, которые умеют пережимать изображения. Некоторые из них мне не подходили по API, другие выдавали неинтересный результат. В общем не буду подробно описывать свои приключения и изучение исходников, но в итоге я пришел к самописному компрессору и следующему набору правил:

Для PNG:

  • pngcrush -q -rem gAMA -rem alla -rem text -ow
  • pngquant --force
  • optipng -strip all -o 3

Для JPG:

  • jpegtran -copy none -optimize -progressive

Для GIF:

  • gifsicle -O 3

Итого весь процесс у меня происходит на клиенте. Кэширование примитивное: запоминаем те же MD5 оптимизированных файлов и больше не предлагаем их пережимать.

Результат

После прогона анализатора и применения его советов приложение похудело до 78.2 мб:

  • Графика: 1513 файлов общим весом в 22.5 мб (было 56.7, -60%).
  • Звук: 94 файла, 49.8 мб (было 59.7, -16.5%). Файлы не сжимались, только были убраны неиспользуемые
  • Скриншоты и иконка: 42 файла, 5.9 мб (было 11.5, -48%). Пришлось немного схитрить: исходная иконка была с разрешением 1024x1024, когда как достаточно всего 256x256. Данная оптимизация была сделана вручную, но я уже размышляю над разделом "другое".

На самом деле работу над анализатором я не считаю законченной. Есть следующие проблемы:

  1. Код нужно порефакторить :)
  2. JPG только оптимизируются - их них выкидывается мусор, сжатие не происходит, хотя здесь тоже можно было бы выиграть.
  3. Со звуком я не делаю вообще ничего. Беглое гугление не выдало утилит, которые делали бы что-нибудь в автоматическом режиме. Только пережимать битрейт на заданный. Если кто-то встречался с подобным кейсом, буду благодарен за ссылки.

Тем не менее, в более простом формате анализатор уже всем доступен, а к концу недели любой пользователь сможет нажать на кнопку "проверка материалов", уйти минут на 10 попить кофе, а, вернувшись, обнаружит свое приложение сбросившим десяток-другой лишних мегабайт.

Попробовать MnCreator можно тут.

+5
В избр. Сохранено
Авторизуйтесь
Вход с паролем
Комментарии
Aleksei Neiman
Еще можно часть контента перенести на сервак и загружать при первом старте или по мере надобности...
Ответить
MnCreator
Визуальный конструктор интерактивных приложений
Чурюкин Артём
Тогда мы будем завязывать создателей приложений на нашу инфраструктуру (которую надо поддерживать), а конечных пользователей — на наличие интернета. Облачный сервис, конечно, в планах, но пока далеких.
Ответить
SPARK
Помогаем бизнесам 24х7
Администрация Spark
Поздравляем, ваша публикация была анонсирована в сообществах издания «Цукерберг Позвонит»!

https://vk.com/smmrussia?w=wall-33393308_346024
https://twitter.com/morketolog/status/608036194614710273
https://www.facebook.com/SMMrussia/posts/957138064311109

Спасибо за интересный материал.
Ответить
Максим Пискунов
А еще, если позволяет движок, можно перегнать текстуры в формат PVR или, на худой конец, использовать 16-битные png.
Ответить
MnCreator
Визуальный конструктор интерактивных приложений
Чурюкин Артём
Это HTML5-движок, так что PVR не катит, а pngquant как раз и преобразовывает изображения в 8-битные png с палитрой.
Ответить
Выбрать файл
Блог проекта
Расскажите историю о создании или развитии проекта, поиске команды, проблемах и решениях
Написать
Личный блог
Продвигайте свои услуги или личный бренд через интересные кейсы и статьи
Написать

Spark использует cookie-файлы. С их помощью мы улучшаем работу нашего сайта и ваше взаимодействие с ним.