Loading, skeleton ou spinner: quando usar cada um

Escolha entre loading, skeleton e spinner conforme o conteúdo, a duração, o bloqueio e a previsibilidade do processo.

Wireframe com três cards em skeleton e um spinner azul localizado em um botão.
Nível de impácto
Médio
Status
Usar com atenção
Nível de evidênica
Evidência moderada

Contexto

Um estado de carregamento informa que a interface está processando algo. Sem esse retorno, uma tela vazia pode parecer quebrada e uma ação pode parecer não ter funcionado. Skeleton, spinner, loading de página, progresso e carregamento progressivo resolvem situações diferentes; a escolha deve considerar o que está carregando, quanto tempo pode levar e se a pessoa ainda pode interagir.

Antes de escolher um indicador, identifique o escopo do carregamento, a previsibilidade da estrutura, a duração esperada e se existe progresso mensurável.

Escolha o padrão pelo contexto

  • Skeleton: use na carga inicial de listas, cards, tabelas ou áreas cujo formato já é conhecido. Reproduza a estrutura aproximada do conteúdo final.
  • Spinner ou loading inline: use em ações assíncronas curtas, como salvar, atualizar, pesquisar ou enviar. Posicione o retorno perto do alvo afetado e evite acionamentos repetidos.
  • Loading de página ou sobreposição: use apenas quando a página ou uma área crítica estiver realmente bloqueada. Preserve o contexto sempre que a interação parcial for segura.
  • Barra ou indicador de progresso: use em tarefas longas quando for possível medir etapas ou percentual. Mostre progresso determinado somente com dados reais; caso contrário, use estado indeterminado.
  • Carregamento progressivo: use em páginas lentas, dashboards, filtros ou fontes múltiplas. Apresente primeiro a estrutura e depois os dados, sem apagar o contexto já disponível.

Em esperas longas, informe o estado atual, indique o que a pessoa pode esperar e ofereça cancelamento, recuperação, tentativa novamente ou uma saída quando isso fizer sentido. Valide a escolha com o tempo real da tarefa e com testes de uso.

Exemplo do Carbon Design System mostrando linhas de skeleton em uma tabela.
Exemplo real: o Carbon Design System usa linhas simplificadas para representar a estrutura de uma tabela enquanto os dados carregam. Relação: demonstra skeleton em um componente baseado em dados, sem transformar controles em placeholders. Fonte: https://v10.carbondesignsystem.com/patterns/loading-pattern/.

Porque isso importa?

Uma espera sem retorno aumenta a incerteza: a pessoa pode interpretar a interface como travada, repetir o clique ou abandonar a tarefa. Um indicador ajuda, mas o padrão errado também cria problemas: um spinner em uma página inteira esconde a estrutura, um skeleton em um controle não explica uma ação e uma porcentagem inventada cria uma expectativa falsa.

Em benchmarks de comércio eletrônico, a Baymard observou ansiedade e repetição de ações durante esperas de alguns segundos, reforçando a necessidade de comunicar que o processo continua e impedir submissões duplicadas. Carbon, Shopify Polaris e Design System GOV.BR convergem na distinção entre skeleton para conteúdo, loading/spinner para processamento e progresso para operações longas ou mensuráveis. A orientação do W3C/WAI acrescenta que o estado precisa ser exposto programaticamente, não apenas animado visualmente.

Base da recomendação

Esta recomendação cruza benchmark de UX da Baymard, documentação de Carbon, Shopify Polaris e GOV.BR, orientação normativa do W3C/WAI sobre mensagens de status e referências de teste e medição da MeasuringU. A evidência é classificada como moderada: há convergência consistente sobre feedback, escopo, acessibilidade e prevenção de ações duplicadas, mas não existe um limite de tempo universal nem um componente obrigatório para todos os produtos. Os valores de 0,1, 1 e 10 segundos associados à Nielsen Norman Group são uma heurística histórica sobre resposta, não uma regra para escolher o loader.

  • Use skeleton quando o formato do conteúdo é conhecido e a área está em carga inicial.
  • Use spinner ou loading inline para uma ação curta ou atualização localizada.
  • Use loading de página somente quando a tela inteira estiver bloqueada.
  • Use progresso determinado quando o percentual ou as etapas forem mensuráveis.
  • Use progresso indeterminado quando a espera existe, mas a duração não é conhecida.
  • Use carregamento progressivo em páginas lentas, dashboards e múltiplas fontes.
  • Adicione status, erro, timeout ou tentativa novamente quando a espera for longa.
  • Não use skeleton em botões, campos, menus, modais ou toasts.
  • Não use spinner de página para uma área pequena.
  • Não mostre percentual sem uma medição real.
  • Não empilhe vários indicadores concorrentes.
  • Não bloqueie a interface inteira sem necessidade.
  • Não deixe um spinner indefinido sem status, erro ou saída.
  • Não dependa apenas de movimento ou cor para comunicar o estado.
Exemplo do Carbon Design System com uma ação de convite acompanhada por loading inline.
Exemplo real: o Carbon Design System mostra loading inline associado à ação de convidar uma pessoa. Relação: demonstra que o retorno deve ficar próximo do alvo em processamento, sem bloquear a página inteira. Fonte: https://v10.carbondesignsystem.com/patterns/loading-pattern/.

Recomendações

Faça

Práticas recomendadas
  • Identifique o que está carregando.
  • Escolha o padrão pelo contexto.
  • Preserve o layout quando possível.
  • Mostre progresso real.
  • Aproxime o indicador do alvo.
  • Evite ações duplicadas.
  • Anuncie o estado à tecnologia assistiva.
  • Teste duração e recuperação.
Interface em wireframe com cards em skeleton e spinner azul localizado em uma ação.
Exemplo correto: o skeleton representa o conteúdo que ainda será carregado, enquanto o spinner aparece apenas junto da ação em processamento. Imagem didática criada para a CamaraUX.

Evite

Práticas a evitar
  • Usar spinner para a página inteira.
  • Desenhar skeleton em controles.
  • Simular percentual.
  • Empilhar loaders.
  • Bloquear sem necessidade.
  • Deixar a espera sem saída.
  • Depender só de animação.
Interface em wireframe bloqueada por spinner vermelho central e outro spinner concorrente no botão.
Exemplo incorreto: a tela inteira está bloqueada por um spinner, há outro loader concorrente e controles receberam placeholders; isso esconde o contexto e impede a interação. Imagem didática criada para a CamaraUX.

Acessibilidade

Informe o estado por texto e semântica, não apenas por movimento, cor ou mudança visual. Para uma atualização breve, use uma mensagem de status apropriada, como role="status" ou uma região aria-live, sem mover o foco desnecessariamente. Se uma região estiver sendo atualizada, considere aria-busy="true" durante o processamento e remova o estado quando o conteúdo estiver pronto.

Para progresso determinado, use um elemento com papel de barra de progresso, nome acessível e valores coerentes de mínimo, atual e máximo. Para spinner ou loading inline, forneça um rótulo acessível, como “Salvando” ou “Carregando resultados”. Evite remover do DOM o controle que recebeu foco; desabilite a ação de forma compreensível sem quebrar o teclado ou a tecnologia assistiva.

Comunique conclusão, falha, timeout e possibilidade de tentar novamente. Garanta foco visível, contraste, leitura coerente e suporte a teclado, zoom e redução de movimento. Consulte as orientações do W3C/WAI sobre mensagens de status e os critérios aplicáveis da WCAG.

Checklist

  • Está claro o que está carregando?
  • O padrão corresponde ao escopo?
  • O skeleton representa a estrutura final?
  • O spinner está próximo do alvo?
  • A página inteira está realmente bloqueada?
  • A porcentagem representa progresso real?
  • O estado indeterminado evita falsa precisão?
  • A pessoa recebe atualização em esperas longas?
  • É possível evitar cliques duplicados sem perder foco?
  • O estado foi testado com teclado, leitor de tela, zoom e redução de movimento?

Referências

Carbon Design System — Loading pattern. Diferencia skeleton, indicadores de loading e carregamento progressivo. Recomenda skeleton para a estrutura de componentes em carga inicial, loading para processamento e progresso para operações mais longas; também alerta contra skeleton em controles e contra loaders concorrentes. Consultar o padrão Loading.

Carbon Design System — Loading e Inline loading. Documenta o uso em esperas mais longas, ações de salvar/atualizar e áreas localizadas. O valor de aproximadamente três segundos aparece como orientação do componente Carbon, não como limite universal para qualquer produto. Loading e Inline loading.

Carbon Design System — Progress bar. Distingue progresso determinado, quando a medida é conhecida, de progresso indeterminado. É uma referência útil para uploads, downloads e tarefas longas, mas o percentual só deve ser usado quando representar o processamento real. Consultar Progress bar.

Shopify Polaris — Spinner. Recomenda spinner para informar processamento e para situações em que o conteúdo não pode ser representado por skeleton, como alguns gráficos. Também orienta não usar spinner para a página inteira, fornecer rótulo acessível e evitar excesso de indicadores. Consultar Spinner.

Design System GOV.BR — Loading. Apresenta indicadores determinados e indeterminados para carregamento de dados, formulários e uploads, com exemplos de role="progressbar", rótulo acessível e valores ARIA. Consultar o componente Loading.

W3C/WAI — Status messages. Define a necessidade de comunicar mensagens de status, como uma operação ocupada ou concluída, de modo que tecnologias assistivas possam percebê-las sem exigir mudança de foco. Consultar a orientação sobre mensagens de status.

Baymard Institute — Grocery e-commerce benchmark. Relata problemas observados quando recursos lentos não informam o processamento, incluindo ansiedade e repetição de cliques. É uma evidência de benchmark em comércio eletrônico; use-a para investigar o próprio contexto, não como um cronômetro universal. Consultar o benchmark.

GitHub Primer — Degraded experiences. Orienta informar carregamento, erro e timeout em experiências dinâmicas e preservar a navegação quando parte do conteúdo falhar. Consultar Degraded experiences.

Nielsen Norman Group — Response times e progress indicators. As heurísticas de tempo de resposta e indicadores de progresso ajudam a discutir expectativa e feedback, mas os valores clássicos de 0,1, 1 e 10 segundos são históricos e não devem ser aplicados como regra rígida. Consultar Response Times e Progress Indicators.

MeasuringU — Medição de UX. Reforça que tempos de tarefa, facilidade percebida e desempenho precisam ser avaliados com métodos de pesquisa adequados; protótipos sem tempo de resposta real não substituem a validação do produto. Consultar a referência sobre medição.

Veja também

Esta recomendação foi útil para você?