DEV Community

Cover image for Sua aplicação é um labirinto? Usabilidade e URL's
Eduardo Oliveira
Eduardo Oliveira

Posted on

Sua aplicação é um labirinto? Usabilidade e URL's

De tempos em tempos, aparecem pessoas comentando sobre a possibilidade do uso de query strings (referência) para armazenar estados ao invés de usar estados "invisíveis" e não rastreáveis (mais adiante você entenderá o que eu quero dizer com não rastreáveis) como se fosse algo super inovador.

A verdade é que estamos voltando às origens.

Introdução

Esse texto tem como objetivo mostrar, de forma conceitual, casos de uso em que esse padrão é bastante utilizado e que, ao longo do tempo, começou a ser negligenciado, principalmente em SPA's (Single Page Applications).

Não será objetivo, aqui, explicar como devem ser feitas as implementações desses comportamentos em frameworks ou bibliotecas. Ainda assim, quando possível, citações e links de referências para documentações serão adicionados.

Partes do texto serão ilustradas com imagens e GIF's de aplicações, reais, em produção. O objetivo não é críticar o trabalho dos seus desenvolvedores.

É importante dizer, também, que algumas dessas animações, em GIF's, podem demorar a carregar, porém esse é um "manual" ilustrado que não seria a mesma coisa sem elas.

Estados Invisíveis

O primeiro tema que iremos discutir são os estados invisíveis e não rastreáveis (esse nome é, de fato, ruim e não sei o motivo pelo qual decidi usar, mas quando falo de rastreabilidade é, basicamente, a rastreabilidade quanto ao histórico do navegador e nos próximos tópicos você entenderá isso).

O problema

Durante o processo de criação de aplicações front-end é comum que sejam utilizados estados (useState no React ou variáveis ou propriedades das classes no Angular) para gerenciar o estado de componentes que lidam com fluxo de dados, como por exemplo filtros e paginação.

Isso resolve o problema: lida com o gerenciamento de estado do fluxo de dados desses componentes. Porém, isso também introduz um novo problema: esses estados são invisíveis e não registram histórico no navegador.

Por exemplo, imagine que tenhamos uma página de estoque, com uma lista de produtos, paginados. Ao entrar nessa página, clicamos para abrir a página 2 e, então, clicamos em voltar, no navegador, voltamos pra página inicial. Veja o GIF abaixo:

Problema ao clicar em voltar numa página

Isso é uma falha na usabilidade do produto, que atinge, inclusive, páginas famosas. Vejam, por exemplo, a página Todos os Cursos do Eu Capacito:

Todos os Cursos do Eu Capacito

Percebam que um fator em comum nesses exemplos é que ao clicarmos em algum número de página a URL não é alterada.

As soluções

Existem, pelo menos, duas soluções ideais para esse problema. Ambas passam pelo uso da URL como estado da página.

Query String

A primeira solução é utilizar a query string para determinar estados. Por exemplo: podemos acrescentar ?page=2 ou ?p=2 na URL para indicar a página e a aplicação consegue lidar com esse parâmetro para determinar qual a página que deve ser exibida.

Um exemplo de produto bastante conhecido, que utiliza query strings para paginar os dados é o GitHub Issues:

Paginação por query parameter

Essa solução pode ser implementada em diversos frameworks, como, por exemplo, em Angular e em React com react-router-dom.

Pathname

Outra forma de solucionar esse problema é utilizar o pathname para armazenar esses estados. Por exemplo, imagine as seguintes rotas: categoria/marketing/ e categoria/marketing/page/2/. É claramente perceptível que a primeira rota indica a página 1 e que a segunda rota indica a página 2.

Esse exemplo foi retirado do blog RockContent.

Infinite Loading

Existe um outro método de paginação de dados que é o infinite loading que carrega e agrega novos itens a parte de baixo a medida que é necessário (seja pelo scroll, seja por um botão de carregar mais). Esse tipo de solução é bastante utilizado quando o conteúdo não tem o próposito de ser bem estruturado (ter começo, meio e fim, por assim dizer). Complicado? vamos explicar com mais calma:

Imagine que você entra na home-page de um site de notícias: você faz isso pra descrobrir as notícias mais recentes e não quer saber quantas páginas de notícia existem.

Você quer rolar a tela até chegar numa data, ou numa notícia que já viu, e ai saberá que o que vem abaixo não lhe interessa mais.

Agora, por outro lado, para que você entenda que certo e errado depende do contexto, imagine que o usuário, vendedor em um marketplace, queira analisar todas as vendas que fez, então ele começa a rolar a página, mais itens são carregados, continua rolando, mais itens são carregados, mas perceba que ele não sabe nem quantos itens ainda faltam pra serem carregados e, o pior ainda, se ele apertar no botão de voltar, como em praticamente todo sistema que usa essa estratégia, ele voltará para a página anterior, e não para a última parcela das compras que foi carregada, pois não há marcação de paginação na URL.

Um exemplo disso pode ser visto no feed do Twitter ou do LinkedIn, percebam que a ideia do feed é a descoberta de novos itens, logo, sem estrutura de começo, meio e fim.

Navegação em Abas

Outro lugar onde esse é um problema de usabilidade claro são no uso das abas, veja o seguinte comportamento:

Orion Business

Perceba que, após alterar a aba, que é o conteúdo principal da página, e clicar em voltar, no navegador, voltamos a página inicial e não a aba anterior. Em alguns casos, mesmo que haja o mapeamento para as URL's, o comportamento não é padrão no browser, veja o comportamento na seguinte página (observe a URL e o comportamento do clique no botão de voltar):

Woovi

Veja um caso de uso onde o mapeamento em URL e o comportamento do navegador funcionam de forma satisfatória:

Shopee

Contraponto: O Contexto que importa

O contexto é o que mais importa. Manter a aba ativa mapeada na URL é uma tática muito legal quando o conteúdo principal é o componente de abas. Agora, imagine que o componente de abas aparece no meio de uma página, entre diversos outros conteúdos: guardar essa aba ativa na URL não faz a menor diferença. Veja o caso da loja da Steam:

Exemplo de Usabilidade da Steam

Nesse caso, vale a mesma lógica que comentamos sobre o uso de abas para descoberta de conteúdo no Infinite Loading.

Filtros de busca

Comentamos muito sobre paginação, navegação em abas, mas o mesmo se aplica para filtros. Como exemplo, podemos olhar a página de produtos, em quase todos os e-commerce com as filtragens: geralmente todas são mapeadas na query string da URL.

Ao mapear os filtros é importante levar em consideração o comportamento dos filtros com relação a filtragem:

  1. sempre quando o usuário alterar um filtro, a listagem já se atualiza com os novos dados;
  2. o usuário altera todos os campos e depois clica em aplicar os filtros.

Algumas das características desses dois comportamentos serão discutidos agora.

Atualizando a listagem filtro por filtro

Observe que a filtragem de um e-commerce, como por exemplo o site da Hering, geralmente se aparenta com categorias:

E-commerce da Hering

Nesse caso, geralmente, usam-se o comportamento de a cada item selecionado a listagem já é atualizada. Percebam, também, que, por conta da categorização dos filtros, o histórico é preservado:

Clicamos em Feminino -> Alfaiataria -> Alongado. Após esse fluxo, clicamos em voltar no navegador e voltamos para somente Alfaiataria. Clicamos novamente em voltar e ficamos somente na página de Feminino.

É visível que, a depender da quantidade de filtros e da forma como se pretenda usar esses filtros, essa pode não ser a melhor escolha.

Selecionando todos os filtros e aplicando

Esse comportamento é, geralmente, mais utilizado quando os filtros possuem uma aparência de filtragem e não de categoria.

Por exemplo, quando os filtros incluem datas de início e de fim, tem-se o seguinte caso de uso: altera-se a data de início pra depois da data de fim. A nova data de início e a data de fim que já estava preenchida não faz sentido.

Um exemplo disso é a tela de extrato da NuInvest:

Extrato da NuInvest

Outro exemplo de uso, bastante comum, para esse tipo de comportamento é quando a API que devolve a listagem é pesada, mal desenhada, não otimizada, etc. e demora muito pra carregar os dados.

Modais e Caixas de Diálogos

Modais e caixas de diálogos são muito bons em diversas situações, mas as vezes esquecemos um detalhe muito importante sobre eles: eles são, basicamente, uma nova página dentro da nossa própria página.

Desse modo, perceba o seguinte comportamento ao tentar escrever uma publicação no LinkedIn e resolver voltar:

Comportamento do LinkedIn

Um dos passos percorridos pelo usuário para chegar ao modal foi perdido ao clicar em voltar.

Para evitar esse tipo de problema, o estado dos modais também devem ser mapeados na URL, de alguma forma. Existem diversas formas de se implementar isso e um exemplo, não convencional, é o Trello que usa o id do card na barra de endereços:

Modal no Trello

Dicas de como melhorar esses pontos da usabilidade

Existem algumas formas de melhorar a usabilidade de aplicações quanto ao mapeamento de URL's. Nas seções abaixo iremos falar sobre algumas dicas de como melhorar isso.

Estude sobre UX

Ler sobre UX é uma boa forma de aprender o comportamento de determinadas interfaces. Isso é interessante mas não resolve, de todo, o problema. Vide o texto UX: Modais, quando (e quando não) usá-los, texto oriundo da Nielsen Norman Group, que não cita o uso das URL's.

Benchmarking

Faça benchmarking em produtos que usa no seu dia a dia. Entre, investigue o comportamento, clique em voltar, clique em avançar, feche o modal clicando no ícone de fechar e clique em voltar. Selecione os filtros, clique em voltar, avançar, mude os filtros um a um, tente mudar a data pra datas inválidas (a data de início posterior a data de fim, por exemplo).

Entenda como os componentes reagem a todos esses casos.

Pense como um usuário

Além de fazer benchmarking, pense como o seu usuário final. O que você achou do comportamento que você encontrou nos teus benchmarkings?

Referências

Produtos Mostrados no Texto


Foto de Aron Visuals na Unsplash

Top comments (2)

Collapse
 
urielsouza29 profile image
Uriel dos Santos Souza

Que texto bom!

Collapse
 
eduardojm profile image
Eduardo Oliveira

Valeu =)