Реалізація кешування зображень в мобільному додатку
Зображення — одна з головних причин видимих тормозів у мобільних додатках. Скролл стрічки з аватарками дергається не тому що пристрій слабий, а тому що декодування JPEG відбувається на main thread у момент, коли ячейка вже має відображатися. Правильний кеш вирішує це, але «просто додати Glide» і «правильно налаштувати кешування» — різні завдання.
Стандартні рішення та де вони буксують
Android: Glide та Coil — найпоширеніші бібліотеки. Glide при дефолтних налаштуваннях кеширует у двох рівнях: memory cache (LruCache з розміром, похідним від доступної пам'яті) та disk cache (DiskLruCache). Coil написана на Kotlin Coroutines та краще інтегрується з Compose через AsyncImage. Проблема виникає коли розмір зображення в мережі не збігається з розміром ImageView: Glide за замовчуванням кеширует вже трансформоване зображення (під конкретний розмір view), що веде до промахів кешу при різних розмірах одного й того ж URL.
iOS: NSCache + ручна логіка або бібліотеки Kingfisher та SDWebImage. Kingfisher — де-факто стандарт для SwiftUI через .setImage(with:). Поширена проблема: кеш не враховує Cache-Control заголовки сервера, і застаріле зображення показується користувачу, поки TTL не спливе вручну.
React Native: react-native-fast-image поверх Glide/SDWebImage. Стандартний Image в RN не має нормального disk-кешу — картинки завантажуються заново при кожному монтуванні компонента, що помітно при навігації між екранами.
Що ми насправді налаштовуємо
Багаторівневий кеш: L1 у пам'яті (швидкий, малий — 20-30 МБ), L2 на диску (повільніший, великий — 200-500 МБ). Розміри підбираються за характером контенту: у новинному додатку з великою кількістю унікальних зображень disk cache важливіший, у месенджері з аватарками — memory cache.
Placeholder та error-state окремо. Показувати пустий простір поки грузиться картинка — гірше, ніж показувати скелетон. Error state має бути явним, але не ломати верстку.
Попередня загрузка (prefetch) для списків: завантажувати наступні N зображень заздалегідь, поки користувач ще не доскролив до них. У RecyclerView — через RecyclerView.RecycledViewPool + DiffUtil. У UITableView — через prefetchDataSource (доступен з iOS 10).
Інвалідація кешу: URL з версією (/avatar.jpg?v=42) або ETag. Без стратегії інвалідації користувачі видять застаріле аватарки після зміни фото профілю.
Часові рамки — два-чотири робочих дні залежно від платформи та складності контенту.







