Все мы знаем, что размер приложения (размер загрузки и размер локальной копии) имеет значение, и существует взаимосвязь между размером приложения и вовлеченностью клиентов. Часто люди принимают решение об использовании программного обеспечения в зависимости от его размера и даже платят за установку мегабайтами. Не говоря уже о том, что количество удалений может возрасти, когда размер приложения увеличивается и пользователи пытаются освободить дисковое пространство на своих устройствах.
Недавно мы представили улучшение в приложении Pinterest версии 9.1 для iOS, которое значительно уменьшило его размер:
В результате мы наблюдаем увеличение количества установок (пользователи скачивают приложения из магазина) в новых версиях с момента внедрения.
В чем проблема
Для контекста — в Pinterest мы используем Bazel для наших сборок iOS. Если вы не знакомы с Bazel, стоит прочитать эту статью.
Для создания наших файлов локализации у нас есть CI-задание, которое автоматически сканирует весь исходный код в приложении (с помощью запроса Bazel) и отправляет их в Mojito для перевода. Это работало хорошо, пока мы не добавили несколько расширений.
Каждое расширение — это модуль со своим собственным файлом BUILD. После сборки Bazel он копирует локализованные строки из основного пакета приложения в каждый пакет расширения. Однако при этом создаются копии Localizable.strings в каждом расширении, что приводит к увеличению общего размера пакета приложения.
Поэтому мы решили исключить копии локализации из расширений.
Исправление
Во-первых, мы обновили файл BUILD, чтобы расширения больше не копировали локализованные строки из основного пакета приложения.
Однако с этим изменением NSLocalizedString не может правильно загрузить локализованную строку. После дальнейшего исследования мы узнали, что оба этих макроса используют +[NSBundle mainBundle], но +[NSBundle mainBundle] фактически возвращает пакет, содержащий «исполняемый файл текущего приложения», который является подпапкой вашего приложения при вызове из расширения. Например: это `/path/to/Pinterest.app/PlugIns/SiriExtension.appex/` вместо `/path/to/Pinterest.app/`. Мы внесли изменение, чтобы установить желаемый путь, чтобы NSLocalizedStringWithDefaultValue мог читать локализованные строки из основного пакета приложения.
Все эти сохраненные изменения — (размер всех Localizable.strings) * (количество расширений, которые имеют дублирование локализаций) — составило около 30% от общего размера приложения.
Долгосрочный план
В дальнейшем мы планируем поместить ресурсы локализации в их соответствующий SDK/расширение вместо того, чтобы полагаться на app bundle. Это даст такие преимущества:
- Каждый бандл будет самодостаточным, поэтому для него не будет требоваться, чтобы основной пакет приложения мог запускать или тестировать локализации, и его можно будет включать в другие приложения.
- NSLocalizedString и API локализации будут естественным образом работать в коде расширения.
- Мы могли бы делать пакеты с открытым исходным кодом.
Есть также другие потенциальные области улучшения, такие как удаление ненужных локализаций для кода, не ориентированного на потребителя, исследование более эффективных по размеру форматов изображений и другие оптимизации на уровне компилятора.