Paginação no desenvolvimento móvel — o que é, tipos e princípio de funcionamento

Autor: IT Sectr Publicado: 2026-03-11 Tempo de leitura: 9 min

Paginação é uma técnica de carregamento de dados por páginas, usada em aplicativos móveis e serviços web para trabalhar com grandes conjuntos de registros. De acordo com a Documentação do Android Developers (2025), a implementação correta da paginação reduz a carga na API, economiza tráfego e melhora a experiência do usuário. O carregamento página por página permite que o aplicativo exiba o conteúdo gradualmente, sem esperar que todos os dados sejam carregados de uma vez.

Pontos principais

  • Paginação — método de carregar grandes conjuntos de dados em porções para otimizar desempenho e tráfego.
  • Paginação Offset usa um deslocamento (page/offset) para navegação — simples, mas instável com inserções frequentes.
  • Paginação Cursor usa um cursor único do último registro — estável quando os dados mudam entre requisições.
  • Paginação Keyset filtra por uma coluna com índice único — eficiente para tabelas grandes sem duplicatas.
  • Paginação baseada em tempo agrupa registros por carimbos de data/hora — conveniente para feeds de notícias e redes sociais.

O que é paginação?

Paginação (do latim pagination — divisão em páginas) é uma técnica de dividir um grande conjunto de dados em porções sequenciais (páginas). Em aplicativos móveis, a paginação é usada ao carregar listas de mensagens, feeds de notícias, catálogos de produtos, histórico de pedidos e qualquer outra coleção com um número potencialmente ilimitado de registros.

Sem paginação, o aplicativo é forçado a carregar todos os dados de uma vez, resultando em longa espera, alto consumo de tráfego e desempenho instável em dispositivos fracos. Uma requisição de API com paginação retorna apenas uma porção de dados e meta-informação para carregar a próxima — assim, o aplicativo controla a quantidade de informação recebida.

As principais métricas de paginação são: tamanho da página (page size) — número de registros por página (geralmente 10–50), e número da página ou cursor — um indicador da posição atual no conjunto. A escolha do tamanho da página depende do tipo de dados: para elementos compactos (nomes) bastam 20–30, para cartões com imagens — 10–15.

Por que a paginação é necessária em aplicativos móveis

Dispositivos móveis têm recursos limitados: RAM, velocidade do processador e limites de tráfego. A paginação resolve três tarefas principais: redução do consumo de memória (apenas elementos visíveis são armazenados em memória), aceleração da primeira exibição (a primeira porção carrega mais rápido que o conjunto todo) e economia de tráfego (os dados são carregados apenas quando o usuário rola a lista).

Principais tipos de paginação

Existem quatro tipos principais de paginação, cada um resolvendo tarefas específicas. A escolha do método depende dos requisitos de consistência de dados, arquitetura da API, tipo de armazenamento e complexidade aceitável de implementação no cliente e servidor.

TipoPrincípio de funcionamentoEstabilidadeVelocidade em grandes volumes
OffsetLIMIT + OFFSET no SQLbaixadiminui com o crescimento do OFFSET
CursorWHERE id > last_idaltaestável (O(log n))
KeysetWHERE key > last_keyaltaestável (O(log n))
Time-basedWHERE created_at < last_timemédiaestável com índice

Quando usar cada tipo

A paginação Offset é adequada para conjuntos de dados estáticos ou raramente atualizados, quando a simplicidade de implementação é importante. Cursor e Keyset são para dados dinâmicos com inserções frequentes. Time-based é para feeds cronológicos onde os registros são ordenados por hora de criação. O padrão GraphQL Relay usa paginação por cursor como o único método recomendado.

Paginação Offset: vantagens e desvantagens

A paginação Offset é o tipo mais simples de carregamento por páginas. O cliente envia os parâmetros page e limit (ou offset e limit), e o servidor aplica SQL OFFSET e LIMIT. Por exemplo, page=2, limit=20 retorna registros 21 a 40. Este método é intuitivo e fácil de implementar em qualquer stack.

python
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items")
async def get_items(
    page: int = Query(default=1, ge=1),
    limit: int = Query(default=20, le=100)
):
    offset = (page - 1) * limit
    items = await fetch_items(offset, limit)
    total = await count_items()
    return {
        "items": items,
        "total": total,
        "page": page,
        "pages": (total + limit - 1) // limit
    }

O problema da inconsistência de dados

A principal desvantagem da paginação Offset é o problema de registros perdidos e duplicados. Se novos registros forem adicionados à tabela entre duas requisições, o OFFSET se desloca: o usuário pode ver o mesmo registro duas vezes ou perder um novo. Isso é crítico para feeds de notícias e chats onde a consistência é importante.

Outro problema é a degradação do desempenho com grandes OFFSET. O banco de dados tem que escanear e pular os primeiros offset registros antes de retornar o resultado. Com offset=100000 mesmo com LIMIT 20, o servidor gastará um tempo notável escaneando. PostgreSQL e MySQL mostram uma queda linear de velocidade à medida que o OFFSET cresce.

Quando Offset ainda é bom

A paginação Offset continua sendo a melhor escolha para: painéis administrativos (dados raramente mudam, navegação por páginas é necessária), relatórios e logs históricos (instantâneo fixo de dados), catálogos com filtros (pode-se ir para qualquer página). Offset também é o mais simples de implementar no cliente — RecyclerView com Paging 3 suporta nativamente.

Paginação Keyset e baseada em tempo

Paginação Keyset usa uma chave única (geralmente a chave primária) para filtrar registros. Em vez de OFFSET, a consulta usa WHERE id > last_seen_id. Isso garante desempenho estável independentemente do número de registros e ausência de duplicatas em inserções, pois novos registros sempre têm um id maior.

sql
-- Paginação por offset (problemática)
SELECT * FROM posts
ORDER BY id
LIMIT 20 OFFSET 100;

-- Paginação por keyset (estável)
SELECT * FROM posts
WHERE id > 100
ORDER BY id
LIMIT 20;

Paginação baseada em tempo

A paginaçao baseada em tempo (ou cursor por tempo) usa o carimbo de data/hora created_at para navegação. O cliente envia o timestamp do último registro carregado, e o servidor retorna registros criados antes ou depois desse timestamp. Este método é popular em redes sociais e feeds de notícias onde a ordem dos registros é determinada pela hora de publicação.

Uma característica da paginação baseada em tempo são possíveis duplicatas se dois registros forem criados no mesmo milissegundo. Para eliminar esse problema, combine uma chave baseada em tempo com um id único: WHERE (created_at, id) < (last_time, last_id). Esse cursor composto garante unicidade de cada registro e ordenação precisa.

Comparação entre Keyset e baseada em tempo

A paginaçao Keyset requer uma coluna com valor único e monotonicamente crescente (id auto-incremento, UUID v7). A baseada em tempo é adequada para qualquer tabela com created_at, mas requer tratamento adicional de duplicatas. A principal diferença: Keyset funciona de forma estável sob qualquer operação de inserção, enquanto a baseada em tempo é sensível a timestamps idênticos.

Como escolher o tipo de paginação para seu projeto

A escolha do tipo de paginação depende da natureza dos dados e dos requisitos de experiência do usuário. Abaixo estão recomendações para cenários típicos no desenvolvimento móvel. Não existe solução universal — cada método tem um domínio onde é ideal.

  • Chat / Mensageiro — Paginação Cursor (por id da mensagem). Novas mensagens aparecem no topo, o cursor não se perde.
  • Feed de notícias — Paginação baseada em tempo (por created_at). Registros ordenados por tempo, cronologia é importante.
  • Catálogo de produtos — Paginação Offset. O usuário pode ir para uma página específica, dados raramente mudam.
  • Histórico de pedidos — Paginação Cursor. Estabilidade é importante porque novos pedidos são adicionados entre carregamentos.
  • Comentários — Paginação Keyset. Cada comentário tem um id único, grandes volumes sem duplicatas.

Implementação no Android com Paging 3

A biblioteca Android Paging 3 suporta todos os tipos de paginação através de PagingSource. Para Offset — PagingSource com chave Int (page), para Cursor — com chave String ou Long (cursor). O PagingSource gerencia automaticamente carregamento, cache e tentativas de erro.

kotlin
class PostPagingSource(
    private val api: PostApi
) : PagingSource<Long, Post>() {

    override suspend fun load(
        params: LoadParams<Long>
    ): LoadResult<Long, Post> {
        val cursor = params.key ?: Long.MAX_VALUE
        return try {
            val response = api.getPosts(cursor, params.loadSize)
            LoadResult.Page(
                data = response.items,
                prevKey = null,
                nextKey = response.items.lastOrNull()?.id
            )
        } catch (e: Exception) {
            LoadResult.Error(e)
        }
    }

    override fun getRefreshKey(state: PagingState<Long, Post>): Long? {
        return state.anchorPosition?.let {
            state.closestItemToPosition(it)?.id
        }
    }
}

Recomendações de tamanho de página

O tamanho da página afeta a velocidade de carregamento e a percepção de desempenho. Para aplicativos móveis, a faixa ideal é 10–25 itens por página. Menos de 10 resulta em muitas requisições à API e scroll irregular. Mais de 25 resulta em carregamento lento da primeira porção em redes lentas.

Para imagens e vídeos, reduza o tamanho da página para 5–10, pois cada elemento requer tempo adicional para carregar mídia. Para listas baseadas em texto (comentários, logs), o tamanho pode ser aumentado para 30–50 registros. Recomenda-se tornar o tamanho da página configurável através da API para que o cliente possa se adaptar a diferentes condições de rede.

Perguntas frequentes

O que é paginação em termos simples?

Paginação é carregar dados em partes, não tudo de uma vez. Como em um livro: você lê uma página, depois vira para a próxima. Em um aplicativo, isso significa que ao rolar uma lista, o próximo lote de dados carrega, não a lista inteira, economizando tráfego e memória.

Como Offset difere de Cursor?

Offset conta registros: “pule 20, retorne os próximos 10.” Se um novo registro for adicionado entre carregamentos, a numeração se perde. Cursor usa o identificador único do último registro: “retorne 10 registros após ID = 100.” Novos registros não afetam a posição.

Qual é o tamanho de página ideal para paginação?

Para aplicativos móveis, o ideal são 10–25 itens. Para listas com imagens — 5–10, para feeds de texto — 20–30. O tamanho depende do tamanho médio de cada elemento: quanto mais pesado o elemento, menor deve ser a página para exibição rápida.

Como implementar paginação no RecyclerView?

Use a biblioteca Paging 3 do Android Jetpack. Ela fornece PagingSource para carregamento, PagingData para fluxos reativos e PagingDataAdapter para carregamento automático ao rolar. A biblioteca suporta paginação Offset, Cursor e Keyset através de um PagingSource personalizado.

O que é scroll infinito e como difere da paginação?

Scroll infinito é um padrão de UI onde um novo lote de dados carrega automaticamente ao se aproximar do final da lista. Paginação é o mecanismo de carregar dados em lotes, e scroll infinito é uma forma de exibi-lo. Uma alternativa é o botão “Carregar mais”.

Resumo

  • Paginação — técnica de carregar dados em porções, essencial para aplicativos móveis com qualquer tipo de lista.
  • Paginação Offset é simples de implementar, mas sofre de inconsistência em inserções e degradação de desempenho em grandes OFFSET.
  • Paginação Cursor usa um identificador único para navegação — estável e eficiente em qualquer volume.
  • Paginação Keyset filtra por chave primária, proporcionando máximo desempenho através do uso de índices.
  • Paginação baseada em tempo agrupa registros por timestamps — ideal para feeds cronológicos e redes sociais.
  • A escolha do método depende da natureza dos dados: para dinâmicos — Cursor/Keyset, para estáticos — Offset, para feeds — Time-based.
  • Paging 3 no Android e soluções padrão de cursor no iOS/web fornecem infraestrutura pronta para qualquer tipo de paginação.

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também