Paginação vs scroll infinito

Prévia grátis 4 min de leitura

Uma página web com 500 registros não consegue renderizar todos de uma vez. Há duas soluções: a paginação, que divide os registros em páginas separadas entre as quais o usuário navega, e o scroll infinito, que carrega mais registros conforme o usuário rola até o fim. Cada padrão tem prós e contras, e uma aplicação Rails bem feita precisa dos dois.

Paginação tradicional: Pagy

Esta aplicação usa a gem Pagy para paginação por offset na área admin. A lista de usuários do admin mostra 10 usuários por página, com links numerados:

# Gemfile
gem "pagy", "~> 43.3"

# config/initializers/pagy.rb
Pagy::OPTIONS[:limit] = 10

O query object limita o número da página às páginas que existem e depois calcula o offset:

# app/queries/admin/identity/list_users_query.rb
def self.call(search: nil, role: nil, page: 1, per_page: Pagy::OPTIONS[:limit] || Pagy::DEFAULT[:limit])
  users = ::Identity::User.order(created_at: :desc)
  # ... filtros de search/role restringem `users` aqui ...
  total_count = users.count
  page = Admin::PageNumber.clamp(page, total_count: total_count, per_page: per_page)
  offset = (page - 1) * per_page
  paginated_users = users.limit(per_page).offset(offset)
  Result.new(users: paginated_users, total_count: total_count)
end

A página 1 mostra os usuários 1 a 10, e a página 2, os usuários 11 a 20. O usuário clica em "Próxima" ou num número de página para navegar, e cada clique é uma requisição completa que troca o conteúdo da página.

O helper de paginação renderiza os controles:

<%# app/views/admin/identity/users/index.html.erb %>
<% pagy = admin_paginator(total_count: @total_count, per_page: @per_page) %>
<div class="mt-8 flex justify-center">
  <%= admin_pagination(pagy) if pagy.pages > 1 %>
</div>

É o padrão clássico. Ele funciona bem em interfaces de admin, em que o usuário precisa pular para uma página específica, guardar uma posição ou compartilhar um link para "a página 3 de usuários". A URL guarda a posição: /admin/users?page=3.

Quando a paginação não serve

A paginação funciona em painéis de admin e resultados de busca. Ela falha em feeds de conteúdo (timelines sociais, threads de comentários, logs de atividade), em que o usuário pensa num fluxo contínuo, e não numa grade numerada.

Os problemas:

  1. Perda de contexto: clicar em "Página 2" troca a página inteira, e o usuário perde a posição de rolagem e o que estava lendo.
  2. Números de página sem sentido: a página 7 de uma thread de comentários não diz nada sobre o conteúdo. Páginas de um feed não têm identidade estável, já que conteúdo novo desloca tudo.
  3. Interrupção: o usuário precisa parar de ler, achar o controle de paginação, clicar, esperar a página e depois achar onde continuar. Cada fronteira de página acrescenta atrito.

Scroll infinito: o fluxo contínuo

O scroll infinito elimina as fronteiras de página. Quando o usuário rola perto do fim, a aplicação busca o próximo lote de registros e o acrescenta à lista, e o usuário continua rolando sem pausa.

sequenceDiagram
  participant U as Usuário
  participant B as Navegador
  participant S as Servidor

  U->>B: Rola para baixo
  B->>B: IntersectionObserver dispara
  B->>S: GET /comments?page=2 (Turbo Stream)
  S->>B: turbo_stream.append + replace load-more
  B->>B: Novos comentários aparecem abaixo dos existentes
  U->>U: Continua rolando sem interrupção

A thread de comentários desta aplicação já usa uma versão manual desse padrão: um botão "Carregar comentários anteriores" que acrescenta comentários via Turbo Streams. O scroll infinito automatiza o clique. Em vez de o usuário clicar nele, o navegador percebe que ele está perto do fim e dispara a carga sozinho.

Quando usar cada um

Padrão Melhor para Exemplos nesta aplicação
Paginação Listas de admin, resultados de busca, tabelas Lista de usuários do admin, lista de cursos do admin
Botão carregar mais Threads de comentários, respostas Discussão nas aulas
Scroll infinito Feeds de atividade, timelines, conteúdo contínuo Ainda não implementado; este curso o constrói

O fator decisivo é o que o usuário quer fazer. No admin, ele quer pular para uma página específica, filtrar e compartilhar URLs. Num feed, quer ler o conteúdo em ordem, sem interrupção.

O que este curso constrói

Nas próximas seis aulas, você vai montar um scroll infinito com ferramentas que esta aplicação já tem:

  • IntersectionObserver (aula 2): a API do navegador que detecta quando um elemento entra na viewport, já usada no navbar desta aplicação para ligar uma sombra durante a rolagem.
  • Turbo Frames (aula 3): como esta aplicação usa frames para conteúdo paginado na área admin.
  • Turbo Streams append (aula 4): como a thread de comentários acrescenta registros novos sem trocar a página, a base do scroll infinito.
  • O controller Stimulus (aula 5): um controller infinite-scroll reutilizável que combina IntersectionObserver com Turbo Streams.
  • Casos-limite (aula 6): estados de carregamento, tratamento de erros, restauração da rolagem e SEO.
  • Juntando tudo (aula 7): o padrão completo, da consulta no servidor ao conteúdo renderizado.
Aula 1 de 7 · grátis

Continue com a aula 2

IntersectionObserver: o detector de scroll

Explica como o IntersectionObserver e um elemento sentinela detectam quando o usuário chega perto do fim da lista.

Com uma conta grátis você também tem os quizzes, seu progresso e suas anotações, e a discussão.

Digite para buscar...