Чому розробка мобільного застосунку доставки їжі буксує на старті
Розробка мобільного застосунку доставки їжі найчастіше ламається не на вітрині, а на стику каталогу, складу та кухні. Меню в застосунку живе своїм життям: позиція позначена доступною, хоча на точці її вже немає, а стоп-лист надходить вручну і з затримкою.
Гість оформлює замовлення, оплата проходить, і лише потім з'ясовується, що страва закінчилася — повернення, зіпсований вечір і видалений застосунок.
Другий типовий провал — завислі замовлення. Статус змінюється на «готується», але далі не рухається: збій платіжного колбеку, загубилася подія від кухонного екрана, кур'єр не отримав призначення.
Без ідемпотентної обробки повторний запит створює дубль замовлення, а без черги з повторами — замовлення просто зникає з потоку.
На піку, коли ввечері п'ятниці кількість одночасних замовлень зростає в рази, синхронні виклики до бази та зовнішніх сервісів складаються в каскадну відмову: падає не одна функція, а весь прийом замовлень.
Ціна цих збоїв рахується не в рядках коду. Кожне зависле замовлення — це дзвінок у підтримку, ручне повернення та гість, який більше не відкриє застосунок. Для ресторану це ще й втрачений виторг у найприбутковішу годину, коли кухня завантажена під зав'язку.
Тому надійність закладають на старті: черга повідомлень із гарантією доставки, ідемпотентні ключі на операції, окремий контур для пікових навантажень і чесна синхронізація стоп-листів між кухнею та каталогом.
Саме тому замовити застосунок доставки «за макетами» недостатньо — спочатку проєктують потік замовлення від кошика до кур'єра та точки відмови на кожному кроці.
Нижче розбираємо, як це закривається на практиці: від архітектури замовлень до синхронізації меню та навантаження в години пік.
Архітектура застосунку доставки: режими роботи та інтеграції
Архітектура застосунку доставки: режими роботи та інтеграції
Архітектура застосунку доставки визначається не екранами, а тим, як система поводиться в трьох станах: звичайне навантаження, пік та обрив зв'язку. Розберемо ключові вузли, де найчастіше губляться замовлення.
Інтеграція з POS та кухнею
Замовлення не повинно «зависати» між застосунком і касою ресторану. Ми будуємо обмін через чергу з підтвердженням: застосунок ставить замовлення, POS його приймає, а за недоступності каси замовлення йде в буфер і повторюється за таймаутом. Підсумок — частка втрачених замовлень падає до нуля навіть при перезапуску каси в момент піку.
Режими роботи кур'єрів
Кур'єр працює в трьох режимах: вільний, везе замовлення, офлайн. Перемикання станів іде через сервер, а не лише на пристрої, — диспетчер бачить реальну картину, а не застарілу. Це прибирає подвійні призначення одного замовлення і скорочує час до призначення кур'єра.
Офлайн-режим застосунку
Кур'єр у під'їзді без мережі повинен продовжувати роботу. Локальний кеш зберігає активне замовлення та статуси, зміни накопичуються і синхронізуються при появі зв'язку. Конфлікти вирішуються за часом події, а не за останнім записом, — статус «доставлено» не відкочується назад.
Масштабування під навантаження
Пікові години дають зростання запитів у рази за хвилини. Горизонтальне масштабування сервісів замовлень і призначення кур'єрів плюс кеш гарячих даних тримають пік без деградації. Час відгуку застосунку залишається стабільним, а не зростає разом із кількістю замовлень.
| Варіант | Коли підходить | Обмеження |
|---|---|---|
| Моноліт з однією базою | Невелика мережа, передбачуване навантаження | Погано переносить піки, складно масштабувати окремі вузли |
| Сервіси з чергою та кешем | Мережа ресторанів, виражені піки | Потребує зрілої експлуатації та моніторингу |
| Готове коробкове рішення | Швидкий старт, типові сценарії | Слабка гнучкість під свої режими кур'єрів і POS |
Зв'язку черг і кешу будуємо на Redis — він тримає гарячі дані призначень і переживає пікові сплески без зростання часу відгуку.
Етапи розробки: від аудиту процесів до передачі застосунку
Розробка мобільного застосунку доставки їжі починається не з макетів, а з розбору того, як замовлення зараз реально влаштовано: хто приймає дзвінок, де губиться адреса, на якому кроці кур'єр чекає підтвердження.
Якщо пропустити цей етап, застосунок просто оцифрує наявний хаос — і пікові години покладуть його так само, як клали кол-центр. Нижче — послідовність, за якою ми ведемо проєкт: кожен етап закінчується артефактом, який можна перевірити, а не звітом «роботи виконано».
- Аудит процесів доставки. Розбираємо шлях замовлення від кошика до дверей: точки підтвердження, ручні операції диспетчера, правила зонування та мінімального замовлення. На виході — карта процесу з вузькими місцями та списком того, що автоматизується, а що залишається ручним усвідомлено.
- Проєктування схеми замовлення. Фіксуємо стани замовлення (створено, оплачено, прийнято кухнею, передано кур'єру, доставлено, скасовано) та переходи між ними, включно зі скасуваннями, частковими поверненнями та недоставкою. Схема узгоджується до початку розробки — правки на цьому кроці коштують години, після релізу — тижні.
- Налаштування інтеграцій. Підключаємо платіжний шлюз, карти та геокодування адрес, канал сповіщень, облікову систему кухні та службу доставки. Для кожної інтеграції описуємо поведінку при недоступності зовнішнього сервісу: замовлення не повинно губитися, якщо платіжний провайдер відповідає із затримкою.
- Складання клієнтського застосунку. Реалізуємо каталог, кошик, оформлення, оплату та трекінг кур'єра на карті. Окремо опрацьовуємо офлайн-сценарій: збережений кошик і повтор замовлення в один тап — це те, що повертає користувача.
- Тестування застосунку доставки. Проганяємо не лише функціональні перевірки, а й пікові сценарії: сплеск замовлень, одночасна зміна адреси та способу оплати, обрив зв'язку в кур'єра. Дивимося час відгуку каталогу та стабільність трекінгу під навантаженням.
- Передача застосунку замовнику. Віддаємо збірки в магазини застосунків, доступи до панелей, схеми інтеграцій та інструкції для підтримки. Навчаємо команду замовника роботі із замовленнями та розбору інцидентів.
Процес побудовано так, що кожен етап можна зупинити й показати результат: карту процесів, схему станів, працюючий прототип, звіт за навантаженням. Опишіть, як у вас влаштована доставка зараз, — повернемося з оцінкою та планом за цими етапами.
Чим відрізняється нативний застосунок від кросплатформного для доставки?
Різниця проявляється не в мові, а в тому, де проходить межа між кодом застосунку та функціями телефона.
Нативна розробка мобільного застосунку доставки їжі пишеться окремо під кожну платформу й отримує прямий доступ до геолокації у фоні, push-каналу, камери, платіжних модулів і віджетів на екрані блокування.
Кросплатформна розробка дає один код на дві платформи, але кожен виклик «заліза» йде через прошарок-міст — і саме на ньому виникають затримки там, де кур'єру важливо бачити своє положення на карті без ривків.
Порівняння підходів упирається в три речі. Перша — швидкість виведення: кросплатформа економить час на старті, бо логіка замовлення, кошик і статуси пишуться один раз.
Друга — доступ до функцій пристрою: фонова геолокація, трекінг замовлення в реальному часі, офлайн-режим і миттєві сповіщення потребують нативних модулів, і на кросплатформі їх або дописують окремо, або миряться з компромісом.
Третя — підтримка застосунку доставки: нативний проєкт дорожчий у розробці, але передбачуваний у поведінці; кросплатформа дешевша на старті, однак при оновленні платформи або сторонньої бібліотеки правки йдуть через спільний шар і можуть зачепити обидві платформи одразу.
На практиці вибір залежить від того, що важливіше для продукту. Якщо застосунок — це карта з кур'єром, живий трекінг, оплата в один тап і сповіщення, які мають приходити секунда в секунду, нативний шлях окупається на утриманні.
Якщо це вітрина ресторанів, каталог, історія замовлень і базова доставка, кросплатформа закриває задачу швидше й дешевше в підтримці — за умови, що критичні до швидкості ділянки все одно пишуться нативно.
Змішаний варіант трапляється найчастіше: спільна логіка та інтерфейс на кросплатформі, а карта, геолокація і push — нативні модулі. Так команда отримує і швидкість виведення, і передбачувану поведінку там, де користувач відчуває затримку.
Ми розбираємо сценарії замовника й говоримо прямо, де кросплатформа дасть виграш, а де впреться в обмеження — до старту, а не після першого релізу.
Кейс: як ми скоротили час збору замовлення в застосунку доставки
Замовник прийшов із працюючим застосунком, але з двома болячками, які з'їдали виторг.
Збір замовлення займав у середньому 4 хвилини 20 секунд, а на вечірніх піках — до 7 хвилин: користувач відкривав кошик, чекав перерахунку вартості доставки, втрачав прогрес при перемиканні на карту й повертався до порожнього екрана.
Частка скасувань на етапі оформлення трималася на 18%, і майже третина звернень до підтримки — «замовлення зникло», «не можу підтвердити». Це класичний випадок, коли розробка мобільного застосунку доставки впирається не у вітрину, а у стан замовлення між екранами.
Ми почали з вимірювань, а не з переписування. Зібрали воронку за кроками оформлення, розмітили час кожного переходу й побачили, що 60% затримки дає синхронний перерахунок кошика на кожен чох: зміна адреси, промокоду, способу оплати. Друге джерело — втрата чернетки замовлення при згортанні застосунку.
Що змінили
Чернетку замовлення винесли в локальне сховище й синхронізували із сервером за подією, а не за кожною дією. Перерахунок кошика став відкладеним: інтерфейс відповідає миттєво, вартість доставки довантажується у фоні з явним індикатором. Промокод перевіряється паралельно з вибором оплати, а не послідовно.
Окремо зайнялися піками. Раніше при зростанні навантаження запити оформлення ставали в загальну чергу з каталогом — тепер в оформлення окремий пріоритет, а повторне надсилання замовлення ідемпотентне: подвійний тап по кнопці не створює два замовлення.
Метрики до і після
| Метрика | До | Після |
|---|---|---|
| Середній час збору замовлення | 4 хв 20 с | 1 хв 50 с |
| Збір на вечірньому піку | до 7 хв | до 2 хв 30 с |
| Скасування на етапі оформлення | 18% | 7% |
| Звернення «замовлення зникло» | ~30% тікетів | ~9% |
Навантаження на підтримку впало майже втричі за цією категорією, а конверсія з кошика в оплату виросла на 11 процентних пунктів — без змін в асортименті та цінах.
Стійкість до піків перевіряли прогоном на подвоєному потоці замовлень: час збору виріс на 15%, а не в рази, як раніше.
Firebase Performance Monitoring використовували, щоб тримати ці метрики під наглядом після релізу, а не лише на етапі вимірювань.
Сумніви перед стартом: сумісність, міграція, доступи
Перед стартом розробки мобільного застосунку доставки їжі замовник зазвичай піднімає три технічні питання: як застосунок ляже на поточний стек, що буде з накопиченими даними і хто отримає доступ до інфраструктури. Це нормальні питання — на них є інженерні відповіді, а не обіцянки.
Що якщо у нас уже є сайт і база замовлень? Сумісність застосунку з наявним контуром перевіряємо до першого рядка коду: дивимося версії API, формати обміну, схеми авторизації.
Якщо бекенд віддає дані в несумісному вигляді — піднімаємо проміжний шар, який приводить контракти до єдиного вигляду, не чіпаючи робочу систему.
Як переносяться дані без простою? Міграція даних іде поетапно: спочатку репліка, потім звірка розбіжностей, і тільки потім перемикання трафіку. Відкат змін передбачено на кожному кроці — повернення до попередньої схеми займає хвилини, а не години.
Хто і що зможе змінювати? Доступи та ролі розводимо за принципом мінімальних прав: розробка, тестування і продакшн — окремі контури, у кожного учасника свій набір дозволів і журнал дій.
Чи можна запустити застосунок, не зупиняючи поточні замовлення?
Так. Реліз виходить на частину користувачів, метрики порівнюються з поточним потоком, і тільки після підтвердженої стабільності трафік переводиться повністю. У разі відхилення — відкат на попередню збірку.
Що замовник отримує на руки:
- конфігурації середовищ — розробка, тест, продакшн;
- схеми інтеграції з наявним бекендом і платіжним контуром;
- політики доступів і ролей з журналом дій;
- регламент міграції даних і план відкату змін;
- документацію застосунку: архітектура, збірка, випуск оновлень;
- інструкції з моніторингу та розбору збоїв на стороні замовника.
Опишіть задачу — повернемося з оцінкою та планом: що перевіряємо на старті, у якому порядку мігруємо і як фіксуємо результат.







