Реалізація пагінації даних у мобільному додатку

Запит списку з 10 000 товарів одним викликом — класична помилка, яку наші інженери бачать у кожному третьому проєкті. API повертає 40 МБ JSON, додаток зависає на парсингу, користувач бачить білий екран на 8 секунд і йде. Ми впроваджуємо пагінацію на рівні контракту між клієнтом і сервером: це забезп

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1734 послуг
Реалізація пагінації даних у мобільному додатку
Середній
від 1 дня до 3 днів

Наші компетенції:

Часті запитання

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    894
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    597

Запит списку з 10 000 товарів одним викликом — класична помилка, яку наші інженери бачать у кожному третьому проєкті. API повертає 40 МБ JSON, додаток зависає на парсингу, користувач бачить білий екран на 8 секунд і йде. Ми впроваджуємо пагінацію на рівні контракту між клієнтом і сервером: це забезпечує зниження навантаження API в 3–5 разів і дає плавну навігацію без затримок. Оцініть API вашого проєкту — зв'яжіться з нами для аудиту.

Реалізація пагінації даних: offset чи cursor?

Більшість розробників беруть offset-пагінацію за замовчуванням — ?page=2&limit=20. Це працює, поки дані статичні. Варто додати живу стрічку, де записи вставляються на початок, і користувач на сторінці 3 пропустить записи або побачить дублі: INSERT на початок зсуває всі offset'и. На таблицях з 500 000+ рядків offset сканує до 100 000 рядків через індексацію B-tree — запит виконується за 200–400 мс.

Cursor-пагінація вирішує проблему: сервер повертає next_cursor, клієнт передає його в наступному запиті. Курсор — це опакний токен (зазвичай base64 від id + timestamp), який фіксує позицію в наборі даних. PostgreSQL-бекенди реалізують це через WHERE id < :cursor ORDER BY id DESC LIMIT 20. Жодних дублів, жодних пропусків. Швидкість запитів залишається стабільною — 50–100 мс незалежно від розміру таблиці.

Порівняння стратегій пагінації
Критерій Offset-пагінація Cursor-пагінація
Простота реалізації Висока Середня (потрібен курсор на бекенді)
Дублі/пропуски при вставці Так Ні
Продуктивність на великих таблицях Погіршується (O(N)) Стабільна (O(1))
Підтримка зміщення до довільної сторінки Так (page=3) Складно (тільки послідовний скрол)
Кешування Легке (сторінки по page) Потрібно зберігати курсори

Чому cursor-пагінація ефективніша за offset?

Cursor-пагінація краще за offset у 3 рази за швидкістю на таблицях від 100 000 рядків — бенчмарки показують зниження часу відповіді з 300 до 90 мс. Крім того, вона гарантує консистентність даних при паралельних вставках. Для стрічок новин, повідомлень у чатах і каталогів з частими оновленнями це обов'язковий вибір.

Як налаштувати кешування за допомогою RemoteMediator?

На Android з Paging 3 курсорна пагінація реалізується через RemoteMediator + PagingSource:

class ItemPagingSource( private val api: ItemsApi, private val query: String ) : PagingSource<String, Item>() { override suspend fun load(params: LoadParams<String>): LoadResult<String, Item> { return try { val response = api.getItems( cursor = params.key, limit = params.loadSize, query = query ) LoadResult.Page( data = response.items, prevKey = null, nextKey = response.nextCursor ) } catch (e: HttpException) { LoadResult.Error(e) } } override fun getRefreshKey(state: PagingState<String, Item>): String? { return state.anchorPosition?.let { anchor -> state.closestPageToPosition(anchor)?.nextKey } } } 

LazyColumn у Compose підключається через collectAsLazyPagingItems() — це готовий binding, який обробляє стани Loading, Error, NotLoading без зайвого коду.

На iOS аналог — compositional layout з UICollectionViewDiffableDataSource і NSDiffableDataSourceSnapshot. Prefetch реалізується через UICollectionViewDataSourcePrefetching: метод prefetchItemsAt викликається за N комірок до краю, що дозволяє запустити мережевий запит заздалегідь. Без prefetch при швидкості скролу більше 500 px/s видно порожні комірки — користувач чекає підвантаження 1–2 секунди.

Як впровадити cursor-пагінацію на Android: покрокова інструкція

  1. Визначте контракт API: сервер повертає next_cursor у JSON-відповіді.
  2. Створіть PagingSource<String, Item>, який передає курсор у loadParams.key.
  3. Підключіть RemoteMediator для offline-кеша: RemoteMediator отримує дані з мережі та зберігає в Room.
  4. У PagingSource реалізуйте getRefreshKey, щоб після оновлення відновити позицію.
  5. Налаштуйте LazyColumn з collectAsLazyPagingItems() і явний LoadStateFooter з кнопкою retry.

Порівняння стратегій кешування: RemoteMediator vs. простий кеш

Параметр RemoteMediator + Room Простий кеш (LruCache)
Offline-доступ Так Ні
Консистентність при оновленнях ETag/Last-Modified Немає механізму
Складність реалізації Середня Низька
Економія трафіку 60–80% 0%
Рекомендація Високонавантажені проєкти Прототипи, статичні дані

Нескінченний скрол та pull-to-refresh

Нескінченний скрол без стану помилки — типова проблема. Мережа пропала на 5-й сторінці, запит завис, користувач скролить вниз і нічого не відбувається. Потрібен явний LoadStateFooter з кнопкою retry.

У Paging 3:

adapter.addLoadStateListener { loadState -> binding.retryButton.isVisible = loadState.source.append is LoadState.Error binding.progressBar.isVisible = loadState.source.append is LoadState.Loading } 

Pull-to-refresh скидає пагінацію до першої сторінки через adapter.refresh() — Paging 3 інвалідує PagingSource і починає заново. На SwiftUI це refreshable модифікатор, який викликає invalidateQueries() у TCA або оновлює @StateObject в'юмоделі. Для впровадження SwiftUI пагінації з кешуванням даних offline використовуйте комбінацію з CoreData та URLSession.

Кеш та offline

Paging 3 + Room — стандартна зв'язка для offline-first. RemoteMediator записує дані в локальну БД, PagingSource читає з Room, а не з мережі. Користувач бачить дані навіть без інтернету, свіжі дані підвантажуються фоном.

Ключовий момент: стратегія інвалідації кеша. Якщо сервер оновив запис, локальна копія застаріє. Рішення — ETag або Last-Modified у заголовках відповіді: клієнт надсилає If-None-Match, сервер повертає 304 без тіла при відсутності змін. Room оновлює лише змінені записи через @Insert(onConflict = OnConflictStrategy.REPLACE). Це знижує обсяг завантажуваних даних на 60–80%.

Що входить у роботу (під ключ)

  • Аудит поточного API та специфікація контракту пагінації.
  • Реалізація cursor/offset-пагінації на клієнті (Android/iOS/крос-платформа).
  • Інтеграція RemoteMediator та Room для offline-режиму.
  • Налаштування prefetch та retry-логіки.
  • Тестування на реальних пристроях з імітацією поганої мережі.
  • Документація коду та рекомендації щодо доопрацювання бекенду.
  • Підтримка після впровадження: 2 тижні консультацій.

Терміни та вартість

Проста offset-пагінація без кеша — 1–2 дні. Cursor-пагінація з RemoteMediator, offline-кешем та retry-логікою — 3–5 днів. Терміни та обсяг роботи узгоджуються індивідуально після аналізу вимог та існуючого API. Ми маємо 5+ років досвіду в мобільній розробці та понад 30 проєктів з пагінацією — довіртеся нашим спеціалістам. Оцініть проєкт: пишіть нам для аудиту пагінації вашого додатка — ми підберемо оптимальне рішення.

Типові помилки при впровадженні пагінації

  • Відсутність prefetch на iOS — порожні комірки при швидкому скролі.
  • Використання offset у стрічці з частими вставками — дублі та пропуски.
  • Ігнорування станів завантаження та помилок: користувач не бачить індикатора.
  • Відсутність кешування — кожен скрол викликає мережевий запит.
  • Неправильний вибір розміру сторінки: 5 елементів — часті підвантаження, 100 — довге очікування.