Урок по треку Архитектура мобильных приложений 6 мин

Кеширование в мобильных приложениях

Кеш в памяти и на диске, HTTP-кеш, картинки, инвалидация, stale-while-revalidate и пагинация.

Кеш делает приложение быстрым и экономит трафик, но добавляет главный вопрос: насколько данные устарели и чьи они. На собесе спросят про уровни кеша, стратегии, инвалидацию и кеш картинок.

Уровни

  • Память: мгновенно, но ограничена и очищается при нехватке. На iOS NSCache (сам вытесняет при давлении памяти), на Android LruCache с размером в байтах.
  • Диск: переживает перезапуск. Файлы в каталоге кеша (система может его очистить) или база.
  • HTTP-кеш: URLCache, кеш OkHttp, учитывают заголовки сервера.
  • CDN и сервер: не на устройстве, но влияют на скорость.

Стратегии чтения

СтратегияКак работаетГде
Cache firstкеш, сеть при промахесправочники
Network firstсеть, кеш при ошибкебаланс, статусы
Stale-while-revalidateкеш сразу, обновление фономленты, каталоги
Без кешавсегда сетькоды подтверждения, платежи

Stale-while-revalidate даёт мгновенный показ и актуальность через секунду: главное обновить список, не сбрасывая позицию скролла.

HTTP-заголовки

  • Cache-Control: max-age=60: можно не ходить на сервер минуту.
  • no-cache: можно хранить, но перед использованием проверить; no-store: не хранить вообще.
  • ETag + If-None-Match, Last-Modified + If-Modified-Since: условные запросы, сервер отвечает 304 без тела, если ничего не изменилось.

Инвалидация

«Самая сложная задача в программировании» на мобильном решается так:

  • TTL по типу данных: курсы минуты, справочник дни;
  • версии в ключе: avatar.jpg?v=17, изменился аватар, изменился URL;
  • события: пользователь изменил профиль, сбросить его кеш; сервер прислал тихий push об изменениях.

Кеш картинок

Типичная архитектура загрузчика (Kingfisher, SDWebImage, Nuke, Coil, Glide, cached_network_image):

  1. Память с уже декодированными и уменьшенными картинками.
  2. Диск с файлами.
  3. Сеть: картинка нужного размера с CDN (с учётом плотности экрана), формат WebP/AVIF/HEIC.

Плюс: декодирование и уменьшение в фоне, склейка одинаковых запросов, отмена для ушедших с экрана ячеек, prefetch по ходу скролла, лимиты по байтам с вытеснением LRU.

Декодированная картинка занимает ширина × высота × 4 байта: фото 4000×3000 это 48 МБ, поэтому оригиналы в ленте недопустимы.

Пагинация и кеш

Для лент курсорная пагинация лучше номеров страниц: при вставке новых записей страницы сдвигаются, и появляются дубли или пропуски. Дубли на стыке страниц всё равно отсекают по id: ключи списков и diffable data source их не переживут.

Приватность

Персональные ответы (/me/orders) кешируются с учётом пользователя и стираются при выходе. Иначе следующий пользователь устройства увидит чужие данные. Удобно делить кеш на общий (каталог) и пользовательский в скоупе сессии.

Частые ошибки

  • Один TTL на всё.
  • Кеш без лимита размера.
  • Новое содержимое по старому URL.
  • Кеш персональных данных, переживающий выход из аккаунта.
  • Оригиналы картинок вместо превью.

Что спросят на собесе

  • Какие уровни кеша бывают и что где хранить?
  • Что такое stale-while-revalidate?
  • Как работают ETag и Cache-Control?
  • Как спроектировать загрузчик картинок для ленты?
  • Почему курсорная пагинация лучше номеров страниц?

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.