Публікація постів: де ламається завантаження зображень
Типова публікація постів влаштована так: користувач вибирає файл, застосунок готує зображення до надсилання повністю — декодує повнорозмірний кадр у пам’ять, стискає та тримає результат до підтвердження сервера.
Поки триває завантаження зображень, стрічка чекає відповіді: оптимістичний пост висить у стані «надсилається», а інтерфейс блокує повторне натискання, щоб не пішло два дублі. На повільному каналі очікування розтягується на хвилини.
Збій надсилання настає передбачувано: зв’язок розривається на останній третині тіла запиту — і все передане втрачається.
Чернетки немає: підготовлений кадр жив в оперативній пам’яті й разом із нею зник, а черга повторів реагує на мережеві помилки, але не на закритий застосунок чи перехід у фон.
Стиснення перед надсиланням відбувається в тому самому потоці: інтерфейс не відзивчивий, а переривання процесу вбиває і підготовку, і сам пост.
Повторюється це на кожному релізі, бо логіка розпорошена по екранах: екран створення поста зберігає стан у себе, надсилання прив’язане до його життєвого циклу, а шар даних не знає про незавершену публікацію постів.
Будь-який рефакторинг екрана — втрата чернетки; оновлення бібліотеки вибору медіа — новий збій на пристроях, де пам’яті під повнорозмірний кадр не вистачає і система припиняє процес.
Розбираємо, як це закривається: підготовка зображення порціями, локальна черга з ідемпотентним ключем і відновлюване довантаження після обриву — так пост переживає і втрату мережі, і перезапуск застосунку.
Що дає кероване завантаження медіа в застосунку
Кероване завантаження медіа — це окремий шар між інтерфейсом і сховищем: черга завантажень, локальний кеш і правила повторних спроб.
Він розводить момент надсилання поста і момент, коли файл реально ліг у сховище, і саме від нього залежить, чи відчуває користувач застосунок швидким.
Відгук інтерфейсу під час надсилання
Пост з’являється у стрічці одразу — з локальної копії, а зображення йде у фоні. Відгук інтерфейсу не залежить від швидкості мережі та розміру знімка: екран не блокується, прогрес видно на мініатюрі, можна згорнути застосунок або перейти на інший екран. Черга завантажень продовжить роботу й синхронізує стан, коли з’єднання повернеться.
Стійкість черги за слабкого зв’язку
Файл передається частинами з контрольними сумами: обірвана сесія відновлюється з останньої підтвердженої частини, а не з нуля. Повторні спроби йдуть із наростаючою затримкою та верхньою межею за кількістю — застосунок не забиває канал і не витрачає батарею в метро.
Обсяг медіа скорочується ще до надсилання: перекодування в WebP і зняття службових метаданих зменшують вагу знімка в 2-4 рази без видимої втрати якості, тому той самий канал віддає помітно більше постів.
Частка невдалих завантажень на нестабільних мережах падає до одиниць відсотків, а серверна частина перестає приймати одні й ті самі файли повторно — обсяг архіву медіа зростає пропорційно до кількості постів, а не до кількості спроб.
Публікація постів: варіанти стиснення та доставки зображень
Компроміс тут завжди один і той самий: де різати якість, хто платить за це часом і яке навантаження отримують сервери. Нижче — чотири схеми, між якими реально обирають під час публікації постів.
| Варіант | Коли підходить | Обмеження |
|---|---|---|
| Стиснення на пристрої | Висока частота постів, слабкі канали | Якість залежить від пристрою, потрібен запас за розміром |
| Оригінал на сервер, обробка там | Гарантована якість зображення | Тривала публікація, пікове навантаження на сервери |
| Гібрид: прев’ю з клієнта, оригінал фоном | Основний сценарій стрічки | Дві фази, потрібне досилання й синхронізація |
| Відкладена обробка чергою | Пачки зображень, масові завантаження | Затримка появи готового варіанта |
Стиснення на пристрої
Клієнт приводить кадр до розумного розміру за довгою стороною, переводить у сучасний формат із втратами та знімає метадані — файл стає в рази меншим за візуально того самого зображення.
Це економить трафік користувача й розвантажує приймальну частину, але якість перестає бути передбачуваною: різні пристрої рахують по-своєму, а слабкий телефон віддає помітно м’якшу картинку.
Серверна обробка та прев’ю
Сервер приймає оригінал, ріже його на набори розмірів під прев’ю в стрічці, повноекранний перегляд і картку, і розкладає по мережі доставки.
Стрічка завантажує легке прев’ю, повний кадр підтягується за потреби — перемикання між екранами залишається миттєвим, а якість зображення однакова для всіх. Зворотний бік — черга обробки, яку потрібно тримати під контролем і вміти перегравати в разі збою.
Етапи робіт: аудит, схема, налаштування, передача
Починаємо з розбору того, як медіа потрапляє в застосунок зараз: де готується зображення, у якому вигляді йде на сервер, що відбувається під час обриву зв’язку. Це точка відліку — без неї будь-яка оптимізація перетворюється на здогадки.
Аудит поточної схеми завантаження
- Збираємо поточний шлях публікації: підготовка файлу, передача, відповідь сервера, поява прев’ю в стрічці.
- Вимірюємо вузькі місця — вагу файлу, що надсилається, час до показу прев’ю, частку невдалих надсилань на слабкій мережі.
- Фіксуємо обмеження: права доступу, обсяги сховища, вимоги модерації до контенту.
Узгодження схеми та перевірка на пристроях
- Проєктуємо схему зберігання: де виконується стиснення, які варіанти зображення віддаються під різні екрани, що залишається в локальному кеші.
- Налаштовуємо стиснення: якість і формат підбираємо під тип контенту, орієнтацію та метадані вирівнюємо автоматично, вагу тримаємо розумною без видимої втрати якості.
- Реалізуємо чергу надсилання: повторні спроби під час обриву, довантаження у фоні, зрозумілий статус публікації в інтерфейсі.
- Перевіряємо на пристроях — слабка мережа, згорнутий застосунок, поворот екрана, нестача пам’яті.
На виході — робочий шлях публікації, документація зі схеми та налаштувань стиснення, навчена команда й чек-лист перевірки для нових релізів.
Схеми, політики зберігання та регламенти на виході
Після релізу в команди замовника залишаються не лише вихідні коди, а й схеми, конфігурації та регламенти, за якими застосунок живе й розвивається без нас.
Ми складаємо їх поруч із кодом, щоб параметри стиснення змінювалися через рев’ю, а не вручну на сервері, а черговий інженер розумів потік медіа з однієї сторінки.
Схеми та конфігурації
- Схема потоку медіа: від вибору файлу в інтерфейсі до появи поста — з точками стиснення, формування прев’ю та повторного надсилання без дублювання публікації.
- Профілі стиснення під сценарії: стрічка, повноекранний перегляд, аватар — з цільовою якістю та граничним розміром файлу для кожного.
- Конфігурація черги завантаження: кількість одночасних задач, час очікування відповіді, правила повторів і поведінка під час обриву зв’язку.
- Політика зберігання медіа: строки життя оригіналу та прев’ю, очищення файлів без прив’язки до поста, порядок видалення на запит користувача.
- Схема доступу: ролі та сервіси з правом читання й видалення об’єктів, порядок видачі тимчасових посилань.
Інструкції для команди підтримки
- Регламент підтримки: як читати журнали невдалих публікацій і відрізняти збій стиснення на пристрої від помилки сховища.
- Перелік типових звернень із готовими кроками розбору: зображення не завантажилося, прев’ю розходиться з постом, публікація пішла двічі.
- Порядок правки параметрів стиснення: де змінювати, як перевірити на тестовому наборі зображень і як повернути попередні значення.
Кейс: скоротили частку невдалих завантажень утричі
Клієнт — мобільний застосунок сервісу оголошень: користувач публікує пост із 4–8 фотографіями прямо з телефона, у русі та на нестабільній мережі.
Початковий сценарій завантажував кадри в повній роздільній здатності одним запитом, а сервер зменшував їх синхронно — під час обриву зв’язку надсилання починалося з нуля.
Метрику рахували за подіями в Sentry: кожна спроба логується з кодом результату та етапом, на якому обірвалася.
Що було до
Частка невдалих завантажень трималася на рівні 21%: кожен п’ятий пост із фото користувач надсилав повторно, а частину кидав на середині. Час відгуку стрічки після публікації сягав 6 секунд — екран чекав, поки сервер приготує похідні розміри.
Архів медіа зростав без обмежень: повторні спроби плодили дублікати вихідних файлів, і сховище подвоювалося приблизно за рік.
Що стало після
Після впровадження стиснення переїхало на пристрій: кадр зменшується за довгою стороною ще до надсилання, а прев’ю з’являється в стрічці одразу — інтерфейс не чекає відповіді сервера.
Завантаження розбите на частини й продовжується з точки обриву, тому частка невдалих завантажень упала до 7% — утричі.
Час відгуку стрічки скоротився до 1–2 секунд, а політика архіву медіа залишає оригінал на 30 днів і зберігає лише похідні — обсяг сховища перестав зростати за того самого трафіку.
Чим відрізняється клієнтське стиснення від серверного?
Клієнтське стиснення — зменшення довгої сторони та перекодування зображення до надсилання: пристрій віддає в мережу вже підготовлений файл без метаданих і зайвих пікселів.
Витрата зв’язку падає в рази, пост іде навіть на слабкому каналі, а серверна частина приймає передбачуваний за розміром потік. Плата — результат залежить від пристрою: на слабкому телефоні перекодування затягується й дає артефакти.
Серверне стиснення — прийом оригіналу та підготовка всіх похідних на стороні сервісу: мініатюр, варіантів під різні щільності екрана, перекодування в актуальні формати. Правила обробки змінюються без випуску нової версії застосунку, а якість виходить однаковою на всіх пристроях.
Обмеження — вихідний файл доїжджає до сервера цілком, і навантаження на сервер зростає на прийомі, декодуванні та зберіганні оригіналів.
Вибір — компроміс між витратою зв’язку, якістю картинки та обробкою на бекенді:
| Підхід | Коли обирати | Обмеження |
|---|---|---|
| Клієнтське стиснення | Слабкий канал, мобільний трафік, великі фото з камери | Якість і швидкість залежать від пристрою, оригінал втрачається |
| Серверне стиснення | Потрібні єдині правила обробки та стабільна якість | Вища витрата зв’язку в користувача, зростає навантаження на прийом і зберігання |
| Гібридна схема | Потрібні і швидкий показ, і збереження оригіналу | Складніша логіка: два проходи й узгодження версій зображення |
За слабкого зв’язку виграє клієнтське стиснення з обмеженням за довгою стороною та фоновим довантаженням оригіналу — користувач швидше бачить свій пост.
На стабільному каналі віддають перевагу серверному: єдині правила обробки простіше підтримувати, а якість не залежить від парку пристроїв.
Часті технічні сумніви та обмеження
Публікація поста із зображенням — це не один запит, а ланцюжок: вибір файлу, стиснення, постановка в чергу, надсилання, відрисовка. Збої на кожному кроці відтворювані, а отже закриваються заздалегідь — до того, як користувач напише «не завантажилося».
Нижче — відповіді на те, що найчастіше випливає під час розбору такої схеми.
Що буде, якщо користувач надішле пост двічі?
Кожному надсиланню присвоюється ідентифікатор операції, а сервер зберігає її результат. Повторний запит із тим самим ключем не створює другий пост, а повертає вже створений — це закриває і подвійний тап по кнопці, і повтор після обриву.
Як поводиться завантаження за слабкого зв’язку?
Файл ріжеться на частини й завантажується з докачуванням: після обриву надсилання продовжується з останньої підтвердженої частини, а не з нуля. Стиснення відбувається на пристрої до надсилання, тому в мережу йде в рази менше даних.
Куди діваються вихідні файли та прев’ю?
Оригінал і зменшені копії зберігаються окремо, прев’ю віддається з кешу на межі мережі. Політика зберігання за розкладом прибирає невикористовувані версії, а видалення поста чистить і оригінал, і похідні.
Чи є обмеження на боці пристроїв?
Так: різні формати зйомки, різний обсяг доступної пам’яті та агресивне завершення фонових процесів на iOS і Android. Тому стиснення відбувається потоково, а черга надсилання відновлюється після перезапуску застосунку.
Обговоримо вашу задачу та повернемося з планом
Щоб повернутися з оцінкою задачі та планом робіт, а не із загальними обіцянками, нам потрібно зрозуміти, як публікація постів влаштована у вашому продукті: звідки приходить зображення, яка якість вважається достатньою, що відбувається під час обриву зв’язку.
Зі свого боку уточнюємо, що вже реалізовано, а що належить зібрати, і де в поточній архітектурі вузькі місця.
Далі — що знадобиться від вас і що ми перевіряємо самі. Розбіжність саме в цих пунктах зазвичай і перетворює задачу з «доробити екран» на «переписати половину завантаження».
- Що вже є: поточний код застосунку, доступи до репозиторію, макети екрана створення поста — без цього оцінка перетворюється на припущення.
- Сценарії публікації: звідки береться зображення (галерея, камера, поширення з іншого застосунку), скільки постів іде одночасно, чи потрібна черга завантаження.
- Вимоги до результату: цільова вага файлу, поведінка за слабкої мережі, формати на виході, що бачить користувач, поки завантаження триває.
- Що уточнюємо самі: стиснення на пристрої, довантаження після втрати мережі, відгук інтерфейсу на повільному каналі.
- У якому вигляді повернемося: оцінка задачі за етапами, план робіт із точками здачі та перелік ризиків.
- Далі за циклом: підтримка застосунку після запуску та передача документації — схеми, регламенти збірки й релізу, інструкції для вашої команди.
Опишіть задачу у вільній формі — повернемося з оцінкою та планом робіт.







