Offset Pagination in mobiele ontwikkeling: wat is het en hoe implementeer je het

Auteur: IT Sectr Gepubliceerd: 2026-03-11 Leestijd: 10 min

Offset Pagination — paginatie met offset — een methode voor het paginagewijs laden van gegevens via HTTP API. De client geeft parameters offset (verschuiving vanaf het begin) en limit (paginaformaat) door, en de server retourneert records vanaf de offset-positie. Volgens REST API Tutorial wordt deze benadering veel gebruikt in RESTful-services vanwege de eenvoud van implementatie. Bij grote hoeveelheden gegevens verliest offset-paginatie echter prestaties door het volledig scannen van de tabel tot de gewenste positie.

Belangrijkste punten

  • Offset Pagination — paginatiemethode waarbij de server N records overslaat en de volgende M retourneert.
  • Eenvoud van implementatie maakt het de standaard voor REST API en mobiele clients.
  • Overslaanprobleem — bij het invoegen van records tussen verzoeken ziet de gebruiker duplicaten.
  • Gegevenssprongen — het verwijderen van records leidt tot paginaverschuiving en verlies van inhoud.
  • Cursor-based paginatie lost deze problemen op via een verwijzing naar het laatste record in plaats van een offset.

Wat is Offset Pagination?

Offset Pagination — is een methode voor het paginagewijs verdelen van gegevens, waarbij het clientverzoek twee parameters bevat: offset (hoeveel records overslaan) en limit (hoeveel records retourneren). De server voert een SQL-query uit met OFFSET en LIMIT, slaat het opgegeven aantal rijen over en retourneert de resultatenset van vaste grootte.

De methode verscheen in relationele databases als de eenvoudigste manier om navigatie tussen pagina's te organiseren en werd overgebracht naar HTTP API met de ontwikkeling van REST-architectuur. Offset Pagination vereist geen statusopslag op de server — elk verzoek is onafhankelijk en bevat alle benodigde informatie voor de selectie.

Volgens API-ontwerponderzoek van Postman (2025) wordt offset-paginatie gebruikt in 72% van de openbare REST API's, wat het de dominante standaard maakt ondanks bekende prestatiebeperkingen bij grote hoeveelheden gegevens.

Structuur van verzoek en antwoord

Een typisch REST-verzoek met Offset Pagination bevat queryparameters offset en limit. Het antwoord bevat een lijst met records van de gevraagde pagina en metadata voor het bouwen van de navigatie-interface.

De parameter limit beperkt het aantal geretourneerde records en beschermt de server en client tegen overmatige belasting. Typische limit-waarden — van 10 tot 50 records per pagina, afhankelijk van de complexiteit van de gegevens.

kotlin
data class PageRequest(
    val offset: Int,
    val limit: Int
)

data class PageResponse<T>(
    val items: List<T>,
    val total: Int,
    val hasMore: Boolean
)

fun RetrofitApi.fetchPage(request: PageRequest): Call<PageResponse<Item>>

Hoe werkt Offset Pagination

Offset Pagination wordt omgezet in een SQL-query met OFFSET- en FETCH NEXT-constructies (of LIMIT in MySQL/SQLite). De databaseserver scant de tabel, slaat het aantal rijen gelijk aan offset over en retourneert de volgende limit rijen. Hoe groter de offset, hoe langer de query duurt.

Het prestatieprobleem houdt verband met het feit dat de database niet direct naar de offset-positie kan gaan — deze moet alle voorgaande rijen lezen en weggooien. Bij offset = 100000 en limit = 20 leest het DBMS 100020 rijen en retourneert slechts 20.

SQL-query onder de motorkap

SQL — de taal waarin de server offset-paginatie uitvoert. In PostgreSQL en MySQL wordt LIMIT gebruikt, in SQL Server en Oracle — OFFSET...FETCH. Verschillende DBMS'en optimaliseren deze query op hun eigen manier, maar het fundamentele scanprobleem blijft hetzelfde.

sql
SELECT id, title, created_at
FROM articles
ORDER BY created_at DESC
OFFSET 100000 ROWS
FETCH NEXT 20 ROWS ONLY;

Consistentieprobleem

Gegevensconsistentie — het belangrijkste nadeel van Offset Pagination bij het werken met dynamische datasets. Als tussen twee gebruikersverzoeken een nieuw record aan het begin van de tabel wordt toegevoegd, verschuiven alle bestaande records. De gebruiker ziet duplicaten of hiaten.

Stel je een tabel voor met 100 records met limit = 20. Op pagina 1 ziet de gebruiker records 1-20. Een beheerder voegt 5 nieuwe records toe. Op pagina 2 ziet de gebruiker records 26-45 in plaats van de verwachte 21-40 — records 21-25 zijn overgeslagen en records 21-25 uit de vorige set zijn gedupliceerd op pagina 1.

Offset vs Cursor-based: vergelijking van benaderingen

Cursor-based pagination — een alternatief voor Offset Pagination, dat een verwijzing naar het laatste record van de huidige pagina gebruikt. In plaats van een numerieke offset geeft de client de identificatie van het laatst ontvangen record door, en de server retourneert de volgende N records erna.

De cursor-based benadering lost het consistentieprobleem op: de cursorpositie verandert niet bij het invoegen of verwijderen, omdat de cursor naar een specifiek record verwijst, niet naar een positie. Het is echter complexer te implementeren — een uniek sorteerbaar veld is vereist (meestal ID of timestamp).

ParameterOffset PaginationCursor-based Pagination
EenvoudHoog — twee numerieke parametersGemiddeld — codering van cursor vereist
ConsistentieLaag — duplicaten bij invoegenHoog — cursor onafhankelijk van wijzigingen
PrestatiesNeemt af met groeiende offsetStabiel bij elk volume
Spring naar paginaJa — naar elke pagina mogelijkNee — alleen sequentiële navigatie
Geschikt voorTabellen <10K records, UI met paginanummersFeeds, oneindig scrollen, grote datasets

De keuze tussen benaderingen hangt af van de interface-vereisten van de gebruiker. Als navigatie met paginanummers en directe sprong nodig is — is Offset Pagination eenvoudiger. Voor oneindig scrollen of nieuwsfeeds hebben cursors de voorkeur.

Keyset pagination

Keyset pagination — een variant van de cursor-based benadering, waarbij filtering plaatsvindt op een unieke sleutel met WHERE in plaats van OFFSET. De SQL-query gebruikt de voorwaarde WHERE id > lastId, waardoor de database een index kan gebruiken zonder weggegooide rijen te scannen.

Volgens PostgreSQL Wiki wordt keyset pagination 100-1000 keer sneller uitgevoerd dan een offset-query bij grote verschuivingen, omdat indexscan de volledige tabeldoorloop vervangt. Nadeel — onmogelijkheid om naar een willekeurige pagina te springen zonder sequentiële doorloop.

Wanneer Offset Pagination gebruiken

Offset Pagination is optimaal voor kleine en middelgrote datasets (tot 10000 records), waar de gebruiker een interface met paginanummers nodig heeft. Typische scenario's — admin-panelen, bestellijsten, catalogi met filtering en paginering.

Voor mobiele applicaties is offset-paginatie geschikt bij het laden van historische gegevens, waarbij het invoegen van nieuwe records zeldzaam of onmogelijk is — bijvoorbeeld de bestelgeschiedenis van een gebruiker, lijst met voltooide taken, transactiearchief. In deze scenario's treedt het consistentieprobleem niet op.

Wordt niet aanbevolen om Offset Pagination te gebruiken voor sociale media-feeds, reactielijsten, chats en andere dynamische datasets met frequente invoegingen. In deze gevallen verslechteren hiaten en duplicaten de gebruikerservaring en vereisen ze extra deduplicatielogica aan de clientzijde.

Hybride benadering

Hybride paginatie combineert offset en cursor: het eerste verzoek gebruikt offset om de beginpagina te tonen, en volgende verzoeken gebruiken cursor voor het laden van oneindig scrollen. Deze benadering is geïmplementeerd in Instagram en Twitter, waar de eerste pagina via cursor wordt geladen, maar offset wordt gebruikt om de positie te berekenen bij terugkeer naar de vorige weergave.

Implementatie van de hybride benadering vereist opslag van de virtuele positie van de gebruiker aan de clientzijde en coördinatie van twee paginatiemechanismen op de server. Volgens de Instagram Engineering-blog gebruikt hun team cursor-based paginatie met een extra veld startCursor, dat offset vervangt voor initieel laden.

Offset Pagination in mobiele applicaties

Mobiele applicaties gebruiken Offset Pagination in combinatie met Retrofit/OkHttp op Android en URLSession/Combine op iOS. Het typische patroon — het laden van de volgende pagina bij scrollen naar het einde van de lijst via RecyclerView.OnScrollListener of UICollectionView prefetching.

Implementatie van offset-paginatie op een mobiele client omvat drie componenten: paginatiebeheerder (slaat huidige offset en hasMore op), lijstadapter (toont elementen en laadindicator) en repository (voert verzoeken uit en verwerkt fouten). Android Jetpack biedt Paging 3 Library, die zowel offset- als cursor-based paginatie uit de doos ondersteunt.

Implementatie op Kotlin met Paging 3

Paging 3 — Android Jetpack-bibliotheek voor het paginagewijs laden van gegevens. Het inkapselt de paginatelogica, inclusief het bijhouden van offset, laadstatusbeheer en automatisch laden bij scrollen. PagingSource definieert sleutels voor de volgende en vorige pagina.

kotlin
class OffsetPagingSource(
    private val api: ApiService,
    private val limit: Int = 20
) : PagingSource<Int, Item>() {

    override suspend fun load(
        params: LoadParams<Int>
    ): LoadResult<Int, Item> {
        val offset = params.key ?: 0
        return try {
            val response = api.getItems(offset, limit)
            LoadResult.Page(
                data = response.items,
                prevKey = null,
                nextKey = if (response.hasMore) offset + limit else null
            )
        } catch (e: Exception) {
            LoadResult.Error(e)
        }
    }
}

PagingSource definieert sleutels prevKey en nextKey voor paginanavigatie. Bij offset-paginatie is prevKey altijd null (kan niet naar vorige pagina zonder geschiedenis op te slaan), en nextKey wordt bij elke lading verhoogd met limit, totdat de server hasMore = false retourneert. Dit is een eenvoudig en voorspelbaar model voor mobiele lijsten.

Veelvoorkomende fouten bij Offset Pagination

Eerste fout — vertrouwen op de volgorde van records zonder sortering. Offset Pagination vereist stabiele ORDER BY-sortering op een uniek veld. Zonder dit kan het DBMS records in willekeurige volgorde retourneren, wat leidt tot willekeurige duplicaten en hiaten tussen pagina's.

Tweede fout — offset gebruiken voor het berekenen van het paginanummer in de interface. De formule page = offset / limit + 1 werkt alleen onder de voorwaarde dat geen enkel record is verwijderd of toegevoegd tussen ladingen. Bij dynamische gegevens wordt het paginanummer onnauwkeurig en ziet de gebruiker incorrecte informatie.

Derde fout — het negeren van timeouts voor query's met grote offset. Bij offset boven 100000 kan een query tientallen seconden duren, de interface blokkeren en serverbronnen verbruiken. Het wordt aanbevolen een maximale offsetwaarde op API-niveau in te stellen (bijv. 10000) en cursor-based paginatie te gebruiken voor grote volumes.

Vierde fout — het niet toevoegen van total count aan het antwoord. Zonder het totale aantal records kan de client het aantal pagina's niet weergeven en paginatie met nummers implementeren. Het berekenen van COUNT(*) op grote tabellen is echter ook duur — voor sets van meer dan 100000 records gebruik je schattingen of beperk je de maximale total-waarde.

Veelgestelde vragen

Wat is het verschil tussen Offset Pagination en Cursor-based?

Offset gebruikt een numerieke verschuiving (offset) om records over te slaan, en cursor een verwijzing naar het laatste record van de vorige pagina. Offset is eenvoudiger te implementeren, maar heeft last van duplicaten bij het invoegen en prestatieverlies bij grote verschuivingen. Cursor is stabiel bij elke verandering in de gegevens.

Wanneer werkt Offset Pagination slecht?

Offset-paginatie is inefficiënt bij offset boven 10000 records vanwege het volledig scannen van de tabel. Het is ook ongeschikt voor dynamische datasets (feeds, chats) waar nieuwe records verschijnen tussen verzoeken — de gebruiker ziet hiaten en duplicaten bij navigatie.

Welke limit is optimaal voor Offset Pagination?

Optimale limit hangt af van de recordgrootte en netwerksnelheid — van 10 tot 50 elementen per pagina. Gebruik voor lijsten met grote afbeeldingen limit = 10-15, voor tekstgegevens — 20-50. Sta de client altijd toe zijn eigen limit op te geven met een maximumbeperking op de server (meestal 100).

Hoe ga je om met duplicaten bij Offset Pagination?

Om duplicaten te bestrijden, gebruik je deduplicatie aan de clientzijde op uniek ID, pas je stabiele sortering op een uniek veld toe of schakel je over op cursor-based paginatie. Android Paging 3 ondersteunt key voor automatische deduplicatie van lijstelementen.

Kan Offset Pagination worden gebruikt met GraphQL?

Ja, GraphQL ondersteunt offset-paginatie via de argumenten offset en limit in de query, hoewel de Relay-specificatie de cursor-based benadering aanbeveelt. De bibliotheken Apollo GraphQL en Relay bieden ingebouwde ondersteuning voor offset-paginatie met automatisch paginastatusbeheer.

Samenvatting

  • Offset Pagination — paginatiemethode met parameters offset en limit voor het overslaan en beperken van records bij het paginagewijs laden van gegevens uit API.
  • Eenvoud van implementatie en onafhankelijkheid van verzoeken maken Offset Pagination de standaardbenadering voor 72% van REST API's (Postman-gegevens, 2025).
  • Prestaties nemen af bij offset boven 10000 vanwege het scannen van de tabel tot de gewenste positie — de database leest alle weggegooide rijen.
  • Consistentieprobleem — het invoegen en verwijderen van records tussen query's leidt tot duplicaten en hiaten in paginresultaten.
  • Cursor-based paginatie lost de problemen van Offset Pagination op via een verwijzing naar het laatste record in plaats van een numerieke offset.
  • Hybride benadering combineert offset van de eerste pagina met cursor-laden voor oneindig scrollen in mobiele applicaties.
  • Aanbeveling — gebruik Offset Pagination voor statische sets tot 10000 records en stap over op cursors voor grote volumes en dynamische gegevens.

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook