Как уменьшить размер шрифтов в мобильном приложении

Встроенные шрифты увеличивают размер приложения вместе с кодом и графикой, но удалять их наугад нельзя: пользователи могут потерять нужные начертания, кириллицу или специальные знаки. Сначала измерьте вклад каждой гарнитуры в финальную сборку, затем сократите дубли и оставьте только подтверждённо нужные данные. Ниже — безопасный порядок действий для Android и iOS.
Сначала выясните, сколько места занимают шрифты
Размер исходного файла на диске и вклад в скачиваемый пакет — разные величины. Сборка может сжать ресурсы, объединить их или разложить приложение по частям. Поэтому начинайте не с папки проекта, а с готового артефакта и сравнивайте одинаковые сборки: до изменения и после него.
В Android Studio откройте APK или Android App Bundle через Build → Analyze APK. APK Analyzer показывает состав пакета, размер файлов и сравнение двух сборок. Найдите каталоги ресурсов со шрифтами; посмотрите как исходный размер, так и оценку размера загрузки. Запишите, какие именно файлы дали заметную разницу. Инструкция есть в документации APK Analyzer (https://developer.android.com/studio/debug/apk-analyzer).
Для iOS сравните архивы одной конфигурации сборки и проверьте, какие файлы шрифтов попали в приложение. Если в проекте несколько targets или конфигураций, убедитесь, что сравниваете один и тот же вариант. У Apple приложение может поставлять собственные шрифты из bundle; ключ UIAppFonts перечисляет файлы, которые система загружает во время работы приложения. Проверьте, что список в Info.plist и фактически включённые в target файлы совпадают.
Составьте простой реестр: имя файла, гарнитура, начертание, языки, экраны, размер в исходниках и вклад в сборку. Это покажет очевидные повторы: один файл случайно включён и как общий ресурс, и в отдельном модуле; старое начертание осталось после редизайна; тот же шрифт лежит в нескольких вариантах приложения.
Удаляйте дубли до изменения файлов шрифта
Самое малорискованное уменьшение начинается с инвентаризации. Соберите в одном месте все ttf, otf, ttc и другие форматы, добавленные приложением, а затем сопоставьте каждый файл с реальным использованием в коде и дизайн-системе. Одно и то же семейство нередко включают несколько раз под разными именами или в двух форматах, хотя приложение использует только один вариант.
Проверьте набор начертаний. Если интерфейс действительно использует обычное и полужирное, не подключайте без необходимости ещё четыре веса, курсив и отдельную декоративную версию. Сначала проверьте рендеринг на реальных экранах: запрос «полужирный» может незаметно получать синтезированное начертание, если нужного файла нет. Удаление должно быть осознанным решением дизайн-системы, а не просто оптимизацией числа файлов.
Сравните шрифт бренда с системным шрифтом платформы. Для служебного текста — например, технической подписи или второстепенного статуса — системная гарнитура может быть уместнее, если этого не запрещает визуальная система. Тогда пользовательская гарнитура останется для заголовков и ключевых сценариев, а не будет занимать место на каждом элементе. Не заменяйте весь интерфейс автоматически: сначала проверьте кириллицу, метрики, переносы и общую узнаваемость продукта.
Подмножество сокращает карту символов, но требует проверки
Если приложение содержит гарнитуру целиком, а интерфейсу нужна лишь часть знаков, можно рассмотреть subset — вариант шрифта с ограниченным набором символов. Например, отдельная декоративная гарнитура для коротких заголовков может не нуждаться в тех же языках и знаках, что основной текст. Но простой список видимых букв не равен полному текстовому набору приложения.
Соберите символы из переводов, названий экранов, сообщений об ошибках, пользовательских данных, форматов дат и чисел. Для русского интерфейса проверьте Ё и ё, Й и й, твёрдый и мягкий знаки, кавычки, тире, знак процента, валюты, скобки и многоточие. Если есть латинские названия, коды, адреса почты или ссылки, проверьте соответствующий набор и знаки, которые могут прийти из внешних данных. Редкий символ может появиться только в имени, адресе доставки или системном сообщении.
Особенно осторожно работайте с OpenType-функциями и комбинируемыми знаками. Видимый символ может собираться из нескольких глифов; соседние буквы могут менять форму при лигатурах или локализованных формах. Подмножество должно сохранять нужные таблицы и правила формирования текста. Документация fontTools Subset (https://fonttools.readthedocs.io/en/stable/subset/) описывает фильтрацию глифов и сохранение OpenType layout-функций; это инструмент для специалистов, а не гарантия, что автоматически полученный файл подходит вашему продукту.
Если лицензия поставщика даёт готовые языковые подмножества, рассмотрите их прежде ручного редактирования файла. Проверьте разрешения: лицензия может ограничивать изменение, распространение или встраивание шрифта. Если сомневаетесь, запросите поставщика. Не выкладывайте модифицированную гарнитуру отдельно от приложения без права на такое распространение.
Не подключайте все версии файла без причины
Переменный шрифт может объединить несколько осей начертания в один файл, однако итоговый размер зависит от самой гарнитуры и используемых возможностей. Иногда один файл проще поддерживать, иногда он тяжелее двух статических начертаний. Решение принимайте по измерениям финальной сборки и экранным сценариям, а не по слову «variable» в описании.
Если интерфейсу нужны только две фиксированные толщины, сравните их отдельные статические файлы с одним variable-файлом. Проверьте, что платформа и используемые компоненты корректно выбирают нужный вес, и что собранный результат действительно меньше. Не включайте всю коллекцию начертаний «про запас»: приложение должно хранить те варианты, которыми пользуется интерфейс.
Конвертация формата тоже не является автоматической экономией. Android и Apple описывают поддерживаемые платформами форматы и способы включения файлов, но повторное сохранение может изменить таблицы, метрики или hinting. Сначала сохраните исходник, сравните сжатый размер и откройте новый файл на целевых устройствах. Проверяйте имя семейства и PostScript-имя: неверная регистрация может заставить приложение незаметно показать системную замену.
Разделяйте поставку только для реального сценария
Google Play использует Android App Bundle, чтобы формировать APK для конфигурации устройства. В частности, приложения могут получать только те ресурсы языка, которые соответствуют языковым настройкам устройства. Это полезно для локализуемых ресурсов, однако нельзя предполагать, что любой файл пользовательского шрифта сам разделится по языкам: отдельно проверьте, как именно он включён в сборку и каким механизмом Android его доставляет. О принципе доставки рассказано в руководстве по Android App Bundle (https://developer.android.com/guide/app-bundle).
На платформах Apple приложение может хранить большие наборы ресурсов в каталогах ассетов, а некоторые ресурсы загружать по запросу. Это архитектурное решение для продукта с действительно редкими дополнительными шрифтами, а не способ спрятать обязательный текстовый шрифт от первого запуска. Если нужный файл не загружен, интерфейс должен оставаться читаемым системным fallback-шрифтом и не ломать макет.
Разделение оправдано, когда есть дополнительная функция или язык, который нужен только части пользователей, и продукт может корректно показывать интерфейс до загрузки соответствующего набора. Для основного интерфейса важнее надёжность: короткая задержка, отсутствие доступа к сети или изменение языка не должны оставлять пустые подписи. Взвесьте также поддержку: чем больше вариантов поставки, тем больше комбинаций приходится проверять.
Проверьте файл и интерфейс после оптимизации
После каждого изменения собирайте новый пакет и прогоняйте контрольный набор экранов. Откройте длинные и короткие подписи, кнопки, формы, сообщения об ошибке и экран, где пользовательский текст может содержать неожиданные символы. Проверяйте не только форму буквы, но и переносы, базовую линию, межстрочные интервалы, цифры и резервное начертание.
Минимальная матрица проверки:
- основной язык и каждый язык, для которого приложение действительно поставляет перевод;
- полный алфавит, Ё/ё, Й/й, пунктуация и специальные знаки сценария;
- обычное, полужирное и курсивное начертания, если они используются;
- системное увеличение текста и экранная ориентация, которые поддерживает продукт;
- холодный запуск без сети, смена языка и состояние, пока дополнительный ресурс недоступен;
- поиск необнаруженных замен системной гарнитурой и ошибок в логах.
В Android проверьте APK Analyzer ещё раз и выполните ручной осмотр на устройстве или эмуляторе. В iOS проверьте, что нужный файл входит в target, зарегистрирован через UIAppFonts, а текст на экране действительно отображается выбранной гарнитурой. Возможность пользоваться собственным шрифтом и его масштабирование — отдельные вопросы: документация Apple описывает добавление шрифта в приложение (https://developer.apple.com/documentation/uikit/adding-a-custom-font-to-your-app) и применение пользовательского шрифта в SwiftUI (https://developer.apple.com/documentation/swiftui/applying-custom-fonts-to-text).
Сохраняйте старую сборку и результаты измерения. Так можно понять, дала ли оптимизация реальный выигрыш и не изменился ли размер из-за других ресурсов. Если новый пакет меньше, но в интерфейсе появились подмены или пропуски знаков, откатите изменение и локализуйте, какой набор символов либо начертание потерялось.
Частые ошибки при уменьшении размера шрифтов
Оставить только буквы из макета. Макеты не включают пользовательские имена, адреса, тексты ошибок и все переводы. Используйте реальные строки и сценарии, затем дополняйте их знаками внешних данных.
Удалить начертания, полагаясь на синтез. Платформа может искусственно утолщить или наклонить базовый файл, но результат визуально и метрически отличается от нарисованного начертания. Сравните реальные экраны до удаления.
Сократить алфавит только в русском экране. Язык текста может меняться внутри строки: смешанные кириллические и латинские названия, электронная почта, номера заказа. Добавьте их в тестовые строки.
Сравнить только исходники. Маленький файл на диске не гарантирует меньшую загрузку, а изменение может повлиять на другие части сборки. Сравнивайте собранные артефакты одним инструментом.
Оптимизировать без проверки лицензии. Техническая возможность преобразовать файл не означает права на подмножество или распространение. Проверьте условия лицензии до преобразования и релиза.
Чеклист перед релизом
- Измерьте вклад шрифтов в установленный и загружаемый пакет до изменений.
- Свяжите каждый файл и начертание с экраном или ролью в интерфейсе.
- Удалите дубли и неиспользуемые файлы, затем пересоберите приложение.
- Для subset подготовьте набор реальных строк, языков, цифр и внешних данных.
- Сохраните нужные OpenType-функции и сверьте право на модификацию.
- Проверьте fallback, системное масштабирование, ориентацию и доступность ресурсов.
- Сравните финальные пакеты и сохраните способ повторить измерение.
Часто задаваемые вопросы
Что в первую очередь удалять, чтобы уменьшить приложение?
Начните с дубликатов и файлов, которые не используются ни в одной роли. Затем проверьте дополнительные начертания и языковые наборы, которые продукт действительно не поддерживает. Не сокращайте алфавит, пока не собрали строки интерфейса и данные пользователей.
Можно ли оставить в шрифте только символы с экранов?
Можно подготовить подмножество, если вы учли все языки, состояния, внешние данные и правила формирования текста. Статический макет не отражает все возможные имена, адреса и сообщения сервера. После сокращения проверьте текст на реальных устройствах и строках.
Variable font всегда занимает меньше места?
Нет. Размер зависит от конкретного файла и набора возможностей. Сравните финальные сборки с используемыми статическими начертаниями и переменным файлом, а затем проверьте рендеринг каждой требуемой толщины.
Стоит ли загружать шрифт после установки приложения?
Это зависит от сценария. Для обязательных подписей и текста первый экран должен оставаться читаемым без сети, поэтому предусмотрите системный fallback. Отложенная доставка имеет смысл для дополнительного языка или функции, если приложение умеет корректно показать состояние до загрузки.
Поможет ли формат WOFF2 внутри Android или iOS?
Не выбирайте формат только по репутации его сжатия для веба. Проверьте форматы, которые официально поддерживает ваш нативный стек и цепочка сборки, и измерьте результат именно в поставляемом приложении.
Можно ли менять файл шрифта без согласования с правообладателем?
Зависит от лицензии конкретной гарнитуры. Проверьте разрешения на встраивание, преобразование и распространение изменённого файла. При неясных условиях попросите письменное разъяснение у поставщика.
Вывод
Сокращайте встроенные шрифты от измерения к изменению: сначала удалите ненужные копии, затем проверьте веса и только после этого рассматривайте подмножества или отдельную доставку. После каждого шага сравните финальную сборку и прогоните строки на целевых устройствах. Если вы создаёте собственную гарнитуру для проекта, подготовить её можно в Fontgenerator (https://fontgenerator.ru/).
Источники
- APK Analyzer — Android Developers (https://developer.android.com/studio/debug/apk-analyzer)
- Android App Bundle — Android Developers (https://developer.android.com/guide/app-bundle)
- Adding a custom font to your app — Apple Developer Documentation (https://developer.apple.com/documentation/uikit/adding-a-custom-font-to-your-app)
- Applying custom fonts to text — Apple Developer Documentation (https://developer.apple.com/documentation/swiftui/applying-custom-fonts-to-text)
- fontTools Subset documentation (https://fonttools.readthedocs.io/en/stable/subset/)