Розробка мобільного застосунку для форуму
Уявіть: форум з 50000 користувачів, 200 розділами та 10 млн постів. Без правильної пагінації під час розробки форум-додатку застосунок гальмує вже на 5000 тем — ми зіткнулися з таким проєктом на продакшні. Клієнт скаржився на зависання при скролі списку тем та падіння продуктивності під час завантаження треда з сотнями відповідей. Довелося повністю перепроєктувати схему БД: замінити offset-пагінацію на cursor-based, впровадити денормалізовані лічильники та переписати запити під покриття індексами. Це прискорило завантаження списку тем у 3 рази (зниження latency на 66%), а сторінки треда — на 40% (покращення на 40%). Розповімо, як побудувати архітектуру, щоб форум літав навіть з мільйоном постів. Наші інженери реалізували понад 50 мобільних форумів на iOS та Android, тому знають усі підводні камені: від code signing до роботи з push-сповіщеннями. Наша команда має 5 років досвіду та понад 50 успішних проєктів.
Основні технічні проблеми при розробці мобільного застосунку для форуму
- Offset-пагінація для списку тем — сповільнюється після 5000 записів, оскільки БД доводиться сканувати всі рядки до зміщення, що призводить до зростання часу запиту на 20% при кожному зміщенні.
- Деревоподібні цитати (Reddit-стиль) — на мобільному екрані їх складно читати; краще використовувати плоску структуру з полем
quote_post_id. - Відсутність денормалізованих лічильників — виклик
COUNT(*)на кожен запит вбиває продуктивність при 10 000+ тредах. - Ігнорування кешування списку розділів та останніх тем призводить до надмірних мережевих викликів.
- Нехтування модерацією — без фільтрації спаму спільнота швидко деградує.
Як ми вирішуємо ці задачі
Для списку тем використовуємо cursor-based пагінацію: курсор по (is_pinned DESC, last_reply_at DESC) для активних тем та по created_at для нових. Цей метод кращий за offset у 3 рази на великих наборах даних: сервер повертає cursor (закодований рядок з timestamp та id), клієнт надсилає його в наступному запиті. Це виключає сканування пропущених рядків та прискорює завантаження в 3 рази на великих наборах (зменшення часу запиту до 80% на 1M+ записах). Таблиця threads містить денормалізовані поля replies_count та last_reply_at, які оновлюються тригером при кожному новому пості — COUNT(*) більше не потрібен.
| Характеристика | Offset-пагінація | Cursor-based пагінація |
|---|---|---|
| Продуктивність на великих даних | Падає після 10К записів | Стабільна до 1М+ записів |
| Підтримка сортувань | Будь-яке сортування | Тільки сортування по індексованому полю |
| Пропуск/дублювання записів | Можливо при вставці | Неможливо |
| Реалізація | Простіше | Трохи складніше |
Cursor-based пагінація — стандарт для мобільних застосунків, де важливий плавний скрол. На практиці економить до 30% часу запиту та знижує навантаження на БД.
Чому денормалізовані поля прискорюють роботу форуму?
Поля replies_count та last_reply_at в таблиці threads оновлюються тригером при кожному новому пості. Це забезпечує:
- Сортування за активністю без
COUNT(*)— економить до 50% часу запиту (порівняно з щомиті виконаннямCOUNT(*)). - Миттєве оновлення бейджів непрочитаних тем на клієнті.
- Просту реалізацію екрана "останні відповіді" без додаткових
JOIN.
Тригер update_thread_reply_count викликається після вставки або видалення поста. Він виконує UPDATE threads SET replies_count = (SELECT COUNT(*) FROM posts WHERE thread_id = NEW.thread_id), last_reply_at = NEW.created_at WHERE id = NEW.thread_id. Хоча це все ще COUNT(*), він виконується тільки при зміні, а не на кожен запит користувача. Для форуму з 1000 постів на годину це дає близько 1000 викликів тригера замість 100 000 запитів COUNT(*) при активному читанні — зниження на 90%.
Як реалізувати цитування постів у мобільному застосунку?
Пости зберігаємо плоским списком з полем quote_post_id. При відображенні цитата рендериться як вкладений блок з сірим фоном, заокругленими кутами та рамкою. Тап по цитаті викликає скрол до оригінального посту через ScrollToRow (iOS) або LazyColumn.scrollToItem (Android). HTML-контент цитати рендериться:
- На iOS: WKWebView для складного форматування (таблиці, зображення) або
NSAttributedStringдля простих текстів. - На Android: Accompanist HtmlText для легкого рендерингу, WebView — тільки якщо потрібні кастомні стилі та JavaScript.
| Компонент | iOS | Android |
|---|---|---|
| Важкий рендеринг | WKWebView | WebView |
| Легкий рендеринг | UILabel + NSAttributedString | Accompanist HtmlText |
| Рекомендація | WKWebView для складного форматування, UILabel для простого | WebView — тільки якщо потрібні кастомні стилі |
Як реалізувати пошук, push-сповіщення та модерацію?
Пошук реалізуємо через PostgreSQL full-text search (tsvector та GIN-індекси) — це забезпечує швидкий повнотекстовий пошук по темах та постах з урахуванням морфології української мови. Для сповіщень використовуємо APNs (iOS) та FCM (Android): при створенні нового поста в підписаній темі сервер надсилає релевантним клієнтам data payload, який тригерить background fetch або появу бейджа. Модерація включає фільтрацію спаму на стороні сервера (за ключовими словами та частотою запитів) та можливість скарги на пост. Адміністратори отримують push-сповіщення про нові скарги.
Згідно з App Store Review Guidelines Section 4.2, застосунок повинен забезпечувати мінімальну якість функціоналу — наш підхід гарантує це.
Процес роботи над проєктом
- Аналітика — узгоджуємо структуру розділів, ролі користувачів, вимоги до модерації та контент-фільтрації.
- Проєктування БД — створюємо схему
boards → threads → posts, налаштовуємо індекси, тригери для лічильників, full-text пошук. - API — REST або GraphQL (Apollo) з cursor-based пагінацією; для пошуку — PostgreSQL full-text search.
- Мобільний UI — розробка екранів на SwiftUI або Jetpack Compose: список розділів, список тем, тред, профіль, редактор поста.
- Інтеграція сповіщень — налаштування APNs та FCM, підписки на теми, deep linking через Universal Links (iOS) та App Links (Android).
- Тестування — навантажувальне тестування пагінації, перевірка офлайн-режиму (кешування останніх даних), юзабіліті-тести.
- Деплой — завантаження в App Store та Google Play, налаштування code signing та provisioning profiles, використання Fastlane для CI/CD.
Що входить у роботу
- Вихідний код мобільного застосунку під iOS та/або Android
- API-сервер (якщо потрібен)
- Документація по схемі БД та API
- Доступи до репозиторію (Git) та CI/CD (GitHub Actions, Fastlane)
- Навчання адміністраторів роботі з модерацією
- Підтримка протягом 1 місяця після запуску
Строки та вартість
- MVP (розділи, список тем, пости, редактор з базовим форматуванням, cursor-based пагінація) — 2-3 тижні
- Повний функціонал (пошук, непрочитані, підписки, модерація, push-сповіщення, deep linking) — 1-3 місяці
Розробка MVP з основними функціями коштує від $3,000, повний функціонал — від $10,000. Вартість розраховується індивідуально після аналізу вимог. Зв'яжіться з нами для оцінки вашого проєкту — ми підготуємо детальний кошторис та строки.
Типові помилки при розробці мобільного форуму
- Використання offset-пагінації без індексу — гальма на 500+ темах.
- Відсутність денормалізованих лічильників —
COUNT(*)на кожен запит вбиває БД. - Рендеринг HTML через UIWebView (iOS) — застарів, гальмує та їсть пам'ять; замінюйте на WKWebView.
- Неврахування offline-режиму — при слабкому з'єднанні форум не відображає кешовані дані.
- Ігнорування App Store Review Guidelines (Section 4.2, 5.1) — ризик відхилення.
- Відсутність обфускації на Android (ProGuard/R8) — витік логіки.
Ми маємо досвід понад 5 років та реалізували 50+ проєктів. Гарантуємо відповідність вимогам магазинів застосунків та високу продуктивність. Оцінимо ваш проєкт безкоштовно — напишіть нам. Замовте розробку мобільного застосунку для форуму вже сьогодні.







