Уменьшаем размер своего iOS приложения

Хочу поделиться способом, который позволит сэкономить несколько мегабайт «лишнего» веса в вашем iOS приложении. Зачем это может понадобиться? Во-первых, если ваше приложение чуть больше 20 Мб, то его нельзя будет скачать по 3G, а только используя Wi-Fi или синхронизацию c iTunes (ограничение со стороны Apple). Ну, а во-вторых, если вы любите все оптимизировать или просто хотите чуть-чуть сократить время загрузки вашего апа.
Все нижеперечисленные пункты я проверял и использовал в своем апе, сэкономив суммарно около 4 Мб. Кажется не очень то и много, но если, например, умножить на 5000 тысяч загрузок в день, то уже получим около 20 Гб сэкономленного трафика. Итак, приступим.

1 Компоновка элементов и нарезка дизайна


Если у вас дизайн уже полностью готов и нарезан и нет желания что-то менять, просто пропустите этот шаг.
Рассмотрим абстрактный пример — дизайнером был нарисован такой прототип:


После нарезки получились следующие картинки:
Фон:


неподвижный статический элемент 1:


неподвижный статический элемент 2:


и элемент 3 — кнопка:


Обычно программисты сильно не заморачиваются и делают так же — верстают фон, потом накладывают элемент 1 и 2 поверх фона, а затем и кнопку. Однако если “вшить” элементы 1 и 2 прямо в фон, то наш новый “сложный” фон:


+ кнопка, будет занимать меньше места, чем старый фон + 2 элемента + кнопка.

1.1 Использование ресурсов от iPhone 4 для iPad (для универсальных апов)

Разрешение iPhone 4 (960x640) не многим отличается от iPad (1024x768). Если это учитывать на этапе проектирование дизайна и UI, то многие элементы дизайна можно просто скопировать с дизайна под iPhone. Например, различные кнопки и прочие небольшие элементы, как правило, одинаковы для iPhone 4 и iPad, поэтому можно не делать новых картинок, а грузить их напрямую c префиксом @2x.
Конечно, данный способ подходит далеко не для все приложений, но не стоит про него забыть.

2. Чаще используйте JPEG формат


Старайтесь сохранять все картинки, которые не требуют альфа-канала, в JPEG — это существенно сократит их размер. Однако, они будут распаковываться на лету, что может незначительно сказаться на производительности.

3. Прогон всех картинок через Image Catalyst


Про него уже писали на хабре (Image Catalyst 2.1) да и с использованием все просто, поэтому рассказывать тут особо нечего, просто скажу, что в результате получается минус процентов 5-10% от первоначального размера.

4. Настройки компиляции


Я использую Xcode 3, поэтому все настройки буду приводить для него. Первое, что надо сделать, это выставить компилятор LLVM 1.6. (В Xcode 4 по умолчанию компилятор LLVM 3.0, поэтому там этого делать не надо):


Затем, убрать опцию Compress PNG Files (т.к у нас все и так уже пожато после Image Catalyst):


После данных настроек финальный билд «худеет» еще на несколько мегабайт.

4.1 Компиляция только под ARMv7

Если вы не поддерживаете старые девайсы (iPhone 3G и iPod 1 и 2 поколения) + минимальная iOS 4.2, то можно компилировать только под ARMv7 архитектуру, это сэкономит еще несколько мегабайт.


Спасибо mark2b за этот способ.

5. Конвертация default.png в JPEG формат (не проверен до конца)


Данный способ я еще не проверил на всех устройствах, поэтому могут быть проблемы с совместимостью. Способ заключается в том, что бы сохранить вашу картинку загрузки (default.png) в JPEG формат, а затем переименовать в PNG. Экономия в размере может достигать до 2-3 раз, по сравнению с оригиналом. Все девайсы, на которых мне удалось проверить данный трюк, отображали картинку корректно и без проблем (скорее всего, есть автоматическая распаковка картинки, перед загрузкой в память).

Если у вас есть какие-то свои способы по уменьшению размера апа или предложения по улучшению/дополнению вышеуказанных, то, добро пожаловать в комментарии.

upd. Потихоньку пополняется список. Спасибо всем за ваши идеи, продолжаем обсуждать, экспериментировать…
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 20

    +3
    Приятно видеть, что моим проект пользуются даже при создании игр для ios.
    Я никогда не писал приложений под ios, но если не ошибаюсь, то приложения запакованы zip (метод сжатия Deflate), а если это так, то их можно и перепаковать и применить более мощный уровень сжатия.
    Вообще может напишу статью про оптимизацию zip, т.к. очень много проектов используют именно его.
      0
      Да, перед отправкой на AppStore все еще жмется zip'ом и действительно можно попробовать поиграться с настройками оного. Спасибо, попробую и отпишусь о результатах.
        +1
        Я уже думал об этом, но тут не важно что мы отправим в Apple, т.к. Apple все равно перепаковывает билд перед тем, как выкладывать. Они меняют подписи, добавляют пару файлов. Не уверен, но возможно добавляют большую иконку. Обычно у меня билд становится на пару метров больше в iTunes, потому стараюсь отправить билд до 17Мб. Если перепаковать билд и за счет сжатия сделать его даже 10Мб — это, по идее, ничего не даст в конечном итоге. Возможно я не прав.
      +1
      По поводу картинок есть много нюансов. Если картинок много, то можно их сложить в атласы, и на лету создавать нужные картинки. Атласы в свою очередь (да и отдельные картинки) — можно сделать так — альфа канал пожать в jpeg (можно поиграть со степень сжатия — но и 60% зачастую хватает), а сами png без альфа канала пожать в 8 битные если палитра позволяет. Опять же собирать в нормальные png на лету.
        +1
        О, а можете рассказать, что за софт так может делать / как это использовать из кода? Слышал про TexturePacker, но он вроде только для cocos'а.
          0
          Я боюсь разочарую. Картинки изначально сохраняются отдельно прозрачность в jpeg отдельно остельное в png. Далее pnglib и jpeglib — получаем цвета в виде массивов, накладываем — и собираем из этого в памяти новую png, собираем ее без сжатия — там простой при этом формат получается — все и дальше грузим ее.
          Т.е. никакой автоматизации.
            0
            В староглиненные времена написал набросал побыстрому скрипт для фотошопа который аталасы генерировал)
            Правда как правило получается удобнее генерировать атлас в рантайме. Особенно когда нужно рисовать буковки.
            Получается что-то типа вот такого:

            GLAtlasGenerator *gen = [[GLAtlasGenerator alloc] init];
            [gen addImageNamed:@"name.png" withKey:@"name"];
            [gen addImageNamed:@"name2.jpeg" withAlphaImageNamed:@"name2_alpha.jpeg" withKey:@"name2"];
            [gen addCharsFromString:numbers fontPrefix:@"numbers" font:fontNumbers];
            ...
            fontsTexture = [gen buildTextureWithFormat:GL_RGBA];
            [gen release];

            Весь профит в том что фонт может быть кастомный. И в атлас можно добавлять только используемые буквы.
            Работает сие дело относительно быстро. Для расположения картинок — используется простейший BSP алгоритм (вроде так зовется).
            0
            Да, поподробнее, пожалуйста
              0
              Андрей, за статью про правильное использование атласов буду очень благодарен ;)
              0
              Если Вы не поддерживаете версии iOS 4.2 ниже, то можно отключить компиляцию для armv6 — iPhone 3G и ниже. Это в половину уменьшит размер приложения, нетто (без ресурсов и прочего мусора).
                0
                В принципе можно отключить компиляцию в armv7 — и будет работать везде! Мы так делали с парой игр. Работает на всем, даже iPhone 4s и iPad2. Сэкономило метров 5.
                  0
                  Спасибо, хороший способ, у меня приложение похудело еще на 1,5 Мб!
                    0
                    А получится залить такое приложение в AppStore? Меня послало.
                      +1
                      минимальная версия iOS (Deployment Target) должна быть 4.3 так как 4.2 еще iPhone 3G поддерживает, который на armv6.
                        0
                        А, вот оно что. Спасибо.
                    0
                    Размер приложения больше зависит от дизайнера, от выбора метода и степени сжатия.
                    Jpg обладает одной из наиболее оптимальной ( размеру \ качеству) компрессией учитывая близлежащие области, то есть некоторый интеллектуальный алгоритм.
                    PNG сжимает по алгоритму LZW схожему с gif.
                    если у вас png весит в 2 раза меньше то возможно дело в том, что вы неверно сохранили сам jpg. Сохранять необходимо через save to web, отключить галочки с вписыванием информации.
                      0
                      Спасибо!
                      Как раз уперся в 20-мегабайтное ограничение — и тут такой подгон.
                      Использовал п.2 и п.3 — сэкономил около 3 МБ

                      По поводу п.1 — именно так и сделал, пришлось вставить только несколько новых файлов -бэкграунды, заточенные по 1024х768.

                      А насчет
                      поэтому можно не делать новых картинок, а грузить их напрямую c префиксом @2x.

                      Это прокатит только если ВЕСЬ арт грузить из кода. С xib-ами такой финт не пройдет.
                      Я делал симлинки на @2x файлы с новым префиксом, а потом прошелся автозаменой по ксибам
                        0
                        Вообщето если в IB написать «имя@2x.png» то будет грузится именно эта картинка.
                        Таким образом для iPhone и iPhone Retina — интерфейс можно нарисовать в одном xib, а для iPad — в файлике с постфиксом ~ipad.
                        0
                        предложу еще один вариант экономии, который я использую на картинках. Когда фон залит регулярным паттерном, можно не делать огромную картинки 640х960 (или 1024х768 для iPad), а вырезать минимальную область и затайлить ее self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@«tiledBack.png»]];
                          0
                          «убрать опцию Compress PNG Files» — этот совет немного снизит производительность загрузки картинки. Дело в том, что последовательность компонент R-G-B не одинакова в PNG-формате и видео-чипе айфона. Поэтому Xcode конвертируется PNG-файлы в формат, готовый к быстрой загрузке в видеопамять без конвертации. Таким образом, снимая этот флажок, вы обязываете рантайм девайса заниматься доп. работой.

                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                          Самое читаемое