Вы открыли Mini App в Telegram, а она тормозит. Кнопки откликаются с задержкой, анимации лагают, и через пару минут приложение вообще перестает реагировать. Это не ваш телефон - это проблема самой Mini App. Миллионы пользователей сталкиваются с этим каждый день, и большинство разработчиков даже не подозревают, что исправить это можно за пару часов. Оптимизация производительности Mini App для мобильных устройств - не про сложные алгоритмы. Это про то, чтобы убрать то, что мешает. Просто и эффективно.
Почему Mini App в Telegram тормозит на телефоне
Mini App в Telegram - это веб-приложение, запущенное внутри мобильного браузера. Он не имеет доступа к нативным API, как обычное приложение из App Store или Google Play. Всё, что вы видите, рисуется через WebView - слабое звено в цепочке. На старых телефонах, даже с 4 ГБ ОЗУ, WebView может работать в режиме экономии ресурсов. И если ваша Mini App загружает 5 МБ JavaScript-файлов, 100 изображений по 200 КБ и 15 библиотек, которые вы не используете - она упадёт. Даже на iPhone 13.
Вот реальный кейс: приложение для управления задачами в Telegram загружало 12 МБ данных при старте. Пользователи жаловались, что приложение «не запускается». На самом деле, оно запускалось - но 8 секунд висело на белом экране. После оптимизации - 1,2 секунды. Разница в 6,5 раза. И это не магия - это устранение лишнего.
Уберите всё, что не нужно
Самая простая и самая недооценённая оптимизация - удалить ненужный код. Вы используете React? Проверьте, сколько библиотек вы подключили. Vue? Тоже. Сколько из них реально нужны для вашего Mini App? В 80% случаев разработчики подключают целые фреймворки, чтобы сделать одну кнопку с анимацией. Это как завести танк, чтобы поехать за хлебом.
Используйте Tree Shaking - это технология, которая автоматически удаляет неиспользуемый код при сборке. В Webpack, Vite или Rollup она включена по умолчанию, но только если вы пишете код правильно. Не импортируйте целый пакет, если вам нужна одна функция:
- Плохо:
import { debounce } from 'lodash' - Хорошо:
import debounce from 'lodash/debounce'
Удалите все библиотеки для работы с DOM, если вы не работаете с ним напрямую. Telegram Mini App уже предоставляет API для взаимодействия с интерфейсом - вам не нужен jQuery, не нужен Axios, если вы используете fetch(). Не нужен Lodash вообще, если вы пишете 3 строки кода на чистом JavaScript.
Оптимизируйте изображения и медиа
Изображения - главный виновник тормозов. Вы загружаете PNG-файлы размером 1500×1500 пикселей для кнопки 48×48 пикселей? Это как везти грузовик с бензином, чтобы заправить мопед.
Превратите все изображения в WebP. Это формат, который сжимает картинки на 30-50% без потери качества. Используйте инструменты вроде Squoosh.app или ImageOptim. Не забудьте про размеры: если кнопка в интерфейсе 48×48 - сохраняйте изображение именно в этом размере. Не загружайте 200×200 и не уменьшайте через CSS - браузер всё равно скачает полный файл.
Для иконок используйте SVG. Они масштабируются без потери качества, и их размер - обычно 1-3 КБ. Не используйте PNG для иконок. Даже если вы думаете, что PNG «лучше», это не так. SVG - стандарт для мини-приложений.
Загружайте изображения лениво (lazy loading). Не грузите все картинки при старте. Используйте атрибут loading="lazy" для тегов <img>. Telegram Mini App API поддерживает это. Если у вас список сообщений с аватарками - грузите их только тогда, когда пользователь прокручивает до них.
Сократите время загрузки JavaScript
JavaScript - это самый тяжёлый ресурс для мобильных устройств. Каждая строка кода требует времени на парсинг, компиляцию и выполнение. На старом Android-телефоне это может занять 2-3 секунды только на загрузку одного файла.
Разбейте ваш код на чанки. Используйте динамический импорт (dynamic imports). Загружайте только то, что нужно на старте. Остальное - по мере необходимости. Например, если у вас есть экран настроек, который открывается редко - загружайте его только при открытии этого экрана.
Пример:
const openSettings = async () => {
const settingsModule = await import('./settings.js');
settingsModule.showSettings();
};
Так вы сократите начальную загрузку на 60-70%. Это работает, потому что Telegram Mini App не требует, чтобы всё было загружено сразу. Он работает как веб-сайт - загружайте только то, что нужно прямо сейчас.
Используйте кэширование и локальное хранилище
Каждый раз, когда пользователь открывает Mini App, он загружает всё заново. Это ужасно неэффективно. Вы можете кэшировать статические ресурсы: CSS, JS, изображения, шрифты. Используйте Service Workers - они работают в Telegram Mini App. Они позволяют сохранять ресурсы на устройстве и загружать их из кэша, даже если интернета нет.
Для данных используйте localStorage или IndexedDB. Не делайте запросы к серверу за одним и тем же списком задач каждый раз. Сохраняйте их локально. Обновляйте только при изменении. Это уменьшает количество HTTP-запросов и ускоряет работу в 3-5 раз.
Проверьте, сколько запросов делает ваша Mini App при старте. Если их больше 10 - вы делаете что-то не так. Оптимально - 2-3 запроса: один за базовыми настройками, один за пользовательскими данными. Всё остальное - локально.
Тестируйте на реальных устройствах
Вы разрабатываете на MacBook Pro с 32 ГБ ОЗУ и SSD. Но ваш пользователь - это человек с Android-телефоном 2020 года, 3 ГБ ОЗУ, и медленным интернетом в деревне. Если вы не тестируете на таких устройствах - вы не знаете, как работает ваше приложение.
Используйте Chrome DevTools - включите режим «Throttling» (замедление сети) и выберите «Slow 3G». Включите «CPU throttling» - поставьте 4x slowdown. Теперь откройте вашу Mini App. Видите, как она тормозит? Это то, что видят ваши пользователи.
Не полагайтесь на скорость в эмуляторе. Эмуляторы не показывают реальную производительность WebView. Тестируйте на реальных телефонах. Возьмите у друга старый Xiaomi, Huawei или Samsung - и проверьте. Если приложение работает плавно на нём - значит, оно будет работать для 90% пользователей.
Оптимизируйте рендеринг и анимации
Анимации - это красиво. Но если вы используете transform: translate или opacity - это нормально. Если вы меняете width, height, margin или padding - это убийца производительности. Каждое изменение этих свойств заставляет браузер пересчитывать расположение всех элементов на странице. Это называется reflow. И он дорогой.
Используйте только CSS-свойства, которые не вызывают reflow: transform, opacity, filter. Для анимаций используйте requestAnimationFrame. Не используйте setInterval или setTimeout для анимаций - они не синхронизированы с частотой обновления экрана.
Если у вас есть список с 50 элементами, которые меняются при прокрутке - не рендерите всё заново. Используйте виртуализацию. Отображайте только те элементы, которые видны на экране. Остальные - скрыты. Это сократит количество DOM-узлов с 50 до 5-10. Это разница между 60 FPS и 10 FPS.
Что ещё можно сделать
Отключите ненужные функции Telegram API. Например, если вы не используете уведомления, не инициализируйте Telegram.WebApp.openTelegramLink() или Telegram.WebApp.showAlert() в начале. Инициализируйте их только тогда, когда пользователь нажимает на кнопку.
Используйте preload и preconnect для критически важных ресурсов. Например, если ваша Mini App загружает шрифт с Google Fonts - добавьте в <head>:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preload" as="font" href="..." type="font/woff2">
Это ускорит загрузку шрифтов на 300-500 мс.
Не используйте CSS-фреймворки вроде Bootstrap. Они добавляют 100+ КБ кода, который вы не используете. Напишите 20 строк стилей на чистом CSS - и вы получите тот же результат, но в 10 раз быстрее.
Итог: 5 шагов к быстрой Mini App
- Удалите все ненужные библиотеки. Оставьте только то, что используется.
- Сожмите изображения в WebP, используйте SVG для иконок, включите lazy loading.
- Разделите JavaScript на чанки и загружайте только необходимое при старте.
- Кэшируйте статические ресурсы через Service Workers, сохраняйте данные в localStorage.
- Тестируйте на реальном старом телефоне с медленным интернетом.
Если вы сделаете эти 5 вещей - ваша Mini App станет быстрее в 3-8 раз. Пользователи будут открывать её чаще, дольше оставаться в ней и меньше жаловаться. Это не про «лучшие практики». Это про то, чтобы приложение работало. Без сбоев. Без задержек. Без раздражения.
Как проверить, сколько весит моя Mini App?
Откройте Telegram Mini App в браузере на компьютере, нажмите F12, перейдите во вкладку Network. Перезагрузите страницу. Внизу вы увидите общий размер всех загруженных файлов. Если это больше 3 МБ - нужно оптимизировать. Идеально - меньше 1,5 МБ.
Можно ли использовать React или Vue в Mini App?
Можно, но с осторожностью. Эти фреймворки добавляют вес. Если вы используете React, выбирайте React 18+ с Concurrent Mode и минимизируйте количество компонентов. Для простых задач лучше использовать чистый JavaScript и библиотеки вроде Preact (всего 3 КБ). Vue 3 тоже легче, чем Vue 2, но всё равно тяжелее, чем чистый HTML + JS.
Почему Mini App работает медленнее на Android, чем на iPhone?
На Android WebView часто работает с ограничениями, особенно на устройствах с низким уровнем памяти. Apple оптимизирует WebView глубже и дает ему больше ресурсов. Android-устройства могут выделять всего 128 МБ памяти на WebView. Если ваша Mini App использует больше - она будет убиваться системой. Это не ошибка - это особенность платформы.
Нужно ли использовать TypeScript?
Нет, не нужно. TypeScript добавляет слой компиляции, который увеличивает время сборки и размер итогового JavaScript-файла. Для Mini App, где важна скорость загрузки, чистый JavaScript предпочтительнее. TypeScript полезен для больших команд и сложных проектов - но не для мини-приложений с 5 страницами.
Как часто нужно обновлять Mini App?
Обновляйте только при появлении критических багов или изменений в API Telegram. Каждое обновление требует, чтобы пользователь заново загрузил приложение. Частые обновления снижают доверие. Лучше сделать один качественный релиз, чем пять быстрых. Если вы добавляете новую функцию - сделайте её опциональной и включайте по запросу пользователя.