Мій футбольний додаток працював ідеально, поки не настав ігровий день
Спершу створення футбольного додатка здавалося простим.
Я планував отримувати матчі, показувати команди, рахунки та оновлювати дані кожні кілька секунд. Під час тестування все працювало. Я використовував дві вкладки та кілька тестових матчів. Все виглядало добре.
Потім настав перший насичений ігровий день.
Сотні користувачів одночасно відкрили додаток. Запити накладалися один на одного. Деякі рахунки, здавалося, змінювалися у зворотному порядку. Додаток отримував одні й ті самі дані окремо для кожного відвідувача.
Я зрозумів, що додаток у реальному часі — це не просто вебсайт, підключений до API. Це система синхронізації даних.
Ось помилки, які я припустився, і те, як я їх виправив:
Уникайте опитування (polling) лише на стороні клієнта У моїй першій версії кожен браузер робив запит на дані кожні п'ять секунд. 1 користувач = 12 запитів на хвилину. 1 000 користувачів = 12 000 запитів на хвилину. Більшість запитів вимагали абсолютно однакових даних.
Використовуйте запити на стороні сервера Я переніс виклики API на сервер. Це дає вам контроль над: • обліковими даними API • кешуванням • обмеженням частоти запитів (rate limiting) • обробкою помилок • форматуванням відповідей
Ніколи не використовуйте ключі в коді на стороні клієнта. Це небезпечно і дорого, якщо хтось викраде ваш ключ.
Створіть шар мапінгу (mapping layer) Я перестав передавати сирі дані API безпосередньо в компоненти. Якщо провайдер змінював назву поля, мій UI ламався. Тепер я спочатку маплю дані провайдера у свій власний внутрішній формат. Це робить мій UI стабільним.
Використовуйте Server Components для швидкості Замість того, щоб показувати екран завантаження, я завантажую початкові матчі на сервері. Користувач бачить контент миттєво.
Впровадьте розумне опитування (smart polling) Додаток не повинен оновлюватися, якщо зараз немає матчів у прямому ефірі. Я додав перевірку, щоб зупинити опитування, коли матчі завершуються. Це економить величезну кількість серверних ресурсів.
Виправляйте стан гонитви (race conditions) Іноді запит B повертається раніше за запит A. Через це здається, що рахунки змінюються у зворотному порядку. Я використовую AbortController, щоб скасовувати старі запити перед початком нових.
Грамотно обробляйте помилки Якщо оновлення не вдалося, не показуйте порожній екран. Залиште видимими останні успішно отримані дані. Рахунок п'ятнадцятисекундної давнини кращий, ніж відсутність рахунку.
Демо-версії потрібно лише відображати дані. Справжній продукт має керувати кешуванням, безпекою та станом.
Ви створювали додатки в реальному часі? Що зламалося, коли прийшли реальні користувачі?
Джерело: https://dev.to/mihailove123/my-football-app-worked-perfectly-until-matchday-started-3i59