Construindo um Frontend com Scroll Infinito e Backend Eficiente em Go: da UI ao JSON de 5000 Produtos
Visão Geral
Neste artigo, vamos criar um projeto de listagem de produtos com scroll infinito, onde o frontend é construído com HTML + Tailwind CSS, e o backend com Go (Golang) + Gin, que entrega dados sob demanda via JSON de forma eficiente e escalável.
Vamos além da estética e exploramos:
Scroll infinito sem paginação explícita
Backend que lê arquivos JSON grandes com stream (sem travar)
Imagens realistas e confiáveis usando
Placehold.coGrid responsivo e visual limpo com Tailwind
Arquitetura performática mesmo com 5000+ itens
Motivação
Um dos desafios comuns ao criar sistemas com grandes volumes de dados é evitar o carregamento completo em memória. Além disso, UIs modernas esperam experiência fluida, como scroll infinito.
Problemas que vamos resolver:
Memória estourando ao carregar JSON com 5000+ registros
Scroll quebrando por falta de gerenciamento de posição
Imagens externas que não carregam ou geram lentidão
Precisamos de fluidez, estabilidade e UX intuitiva
Arquitetura do Projeto
loja-scroll/
├── backend/
│ ├── main.go # API REST com Gin
│ └── produtos.json # Gerado via script com 5000 itens e imagem para cada
└── frontend/
└── index.html # Tailwind + JavaScript puro com scroll infinito
Backend com Go — Entrega sob demanda (streaming JSON)
Estratégia:
Lê o arquivo
produtos.jsoncomo stream usandojson.DecoderMantém controle de estado no servidor
Entrega 20 itens por chamada ao endpoint
/produtosResponde
{ fim: true }quando os dados acabam
Código principal do servidor:
var (
decoder *json.Decoder
arquivo *os.File
offsetMux sync.Mutex
offsetSet bool
)
Ao receber uma requisição:
func produtosHandler(c *gin.Context) {
offsetMux.Lock()
defer offsetMux.Unlock()
if !offsetSet {
initDecoder("backend/produtos.json")
offsetSet = true
}
var produtos []Produto
for i := 0; i < 20 && decoder.More(); i++ {
var prod Produto
decoder.Decode(&prod)
produtos = append(produtos, prod)
}
c.JSON(200, gin.H{
"produtos": produtos,
"fim": len(produtos) == 0,
})
}
Esse design garante:
Leitura sob demanda
Baixo uso de memória
Entrega controlada com offset interno
Imagens que funcionam: Placehold.co
A maioria dos placeholders (Unsplash, Picsum) falham ou bloqueiam uso automatizado. A melhor solução: placehold.co
Exemplo de URL confiável:
https://placehold.co/400x200?text=Produto+123&font=roboto
Gerador de JSON com imagem para cada produto:
imagem := fmt.Sprintf("https://placehold.co/400x200?text=Produto+%d&font=roboto", i)
Cada produto terá sua própria imagem com texto renderizado, 100% garantido de carregar.
Frontend com Tailwind CSS e Scroll Infinito
O frontend usa:
fetch('/produtos')conforme scrollgriddo Tailwind para layout responsivohover,shadow,transitionpara efeitos visuais suaves
HTML de um card:
<div class="bg-white rounded-xl shadow-md hover:shadow-xl transition">
<img src="${p.imagem}" class="w-full h-48 object-cover bg-gray-200">
<div class="p-4">
<h2 class="text-lg font-semibold truncate">${p.nome}</h2>
<p class="text-blue-600 font-bold text-lg">R$ ${p.preco.toFixed(2)}</p>
</div>
</div>
Script de scroll infinito:
window.addEventListener('scroll', () => {
if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 300) {
carregarProdutos();
}
});
Performance Real
Mesmo com 5000 produtos, o projeto:
Carrega rápido
Usa pouco processamento
Mostra imagem para todos os cards
Mantém experiência fluida
Teste Local
Clone o projeto
Gere o
produtos.jsoncom o script GoRode com:
cd backend go run main.goAbra http://localhost:8080
Conclusão
Com Go, Gin e Tailwind, conseguimos entregar um sistema de produtos com scroll infinito, fluido, performático e bonito, mesmo com mais de 5000 itens.
Você pode usar esse padrão em:
Listagens de notícias
Feed de redes sociais
Catálogos de produtos
Galerias de fotos
E tudo com alta performance, mesmo em ambientes simples.
Link Github: https://github.com/williamkoller/golang-process-data-on-demand

