Pular para o conteúdo
Blog
Decidir e comprar software sob medida

O que muda num sistema quando o app precisa funcionar sem sinal

Pedro CunhaPublicado em atualizado em 13 min de leitura

Em resumo

Offline-first não é uma funcionalidade do aplicativo: é uma decisão que muda o banco, o servidor e o escopo do produto — principalmente o que não vai para o aparelho. E um app que promete offline e trava é pior que um app online honesto: a diferença entre os dois está em detalhes que quase nunca aparecem na proposta.

O que é offline-first, e por que não é cache#

Cache guarda a resposta de uma requisição que já aconteceu, para não repeti-la. Serve para acelerar leitura e some quando o assunto é escrita: o que o usuário cria sem sinal não tem onde morar.

Offline-first é outra coisa. O aplicativo tem um banco de dados próprio no aparelho, e é dele que a tela lê — lista, busca, mapa, formulário. O servidor entra depois, em segundo plano. A rede deixa de ser condição para o trabalho acontecer.

O teste leva dez segundos: em modo avião, tente criar alguma coisa. Um app com cache falha ao gravar; um app offline-first cadastra, e o registro continua lá depois de fechar e reabrir.

A formulação mais conhecida dessa ideia é o ensaio "Local-first software: you own your data, in spite of the cloud", publicado pelo laboratório Ink & Switch em 2019, com Martin Kleppmann entre os autores. Dos sete ideais que ele lista, o mais relevante para software corporativo é o mais simples: a operação responde sem depender de ida e volta à rede.

Quando offline-first vale — e quando é dinheiro jogado fora#

O critério não é o setor da empresa. É onde o trabalho acontece.

Vendedor externo que atende o interior de três estados trabalha onde o sinal é hipótese, não fato. Operador que faz checklist de equipamento em obra, idem. Aluno que registra treino na academia costuma estar no subsolo. Nesses casos, o momento em que o sistema é usado é justamente o momento em que a rede não está. E vale o contrário: se a pessoa usa o sistema sentada, com Wi-Fi, offline-first é complexidade permanente em troca de um problema que ela não tem.

A segunda pergunta, quando a primeira dá "sim", é o que precisa funcionar sem rede. Só consultar é um problema; registrar é outro, bem maior, porque exige uma fila de saída e tudo que vem com ela.

DecisãoO que ela impõeQuando vale
Banco local no aparelhoespaço e memória no dispositivo; recorte explícito de quais dados descemo trabalho acontece longe de rede confiável
Fila de escrita (envio posterior)ordem entre registros, repetição em caso de falha e política para escrita recusadaa pessoa registra em campo, não só consulta
Identificador gerado no aparelhoo servidor deixa de ser quem batiza o registroqualquer criação offline
Sincronização visível na interfacetelas e textos que a maioria dos apps não temsempre — é o que evita o usuário achar que travou

Nenhuma dessas linhas é opcional depois que a primeira é escolhida. É por isso que offline-first é decisão de escopo, e não ajuste fino no fim do projeto.

Por que um app offline ruim é pior que um app online honesto#

O sistema que a Reticar Motores usava antes do nosso já tinha comportamento offline — e era exatamente ele a origem da dor: a sincronização disparava a cada abertura e bloqueava o aplicativo inteiro enquanto rodava, piorava em conexão lenta ou instável, e o usuário não tinha como saber o que estava acontecendo nem se o que registrou havia subido.

O efeito numa equipe é previsível e caro: a pessoa deixa de confiar no aplicativo e volta a anotar no papel para digitar depois. Um app honestamente online, que diz "sem internet" e não finge, gera menos retrabalho que um app que promete autonomia e entrega congelamento.

A diferença entre os dois não é conceitual — é de granularidade, e são quatro decisões de implementação:

  • Baixar em páginas pequenas. No app da Reticar, cada página do download traz 100 registros. Nosso projeto base usa páginas muito maiores, e para uma base grande isso significa segurar a interface por tempo demais.
  • Aplicar em lotes. Quando a página é grande, os registros são gravados no banco local em lotes de 40, e não de uma vez.
  • Devolver a tela ao usuário entre os lotes. Entre um lote e outro, o aplicativo entrega o processamento de volta para a interface tratar gesto e animação. É essa linha que separa "sincronizando em segundo plano" de "travou".
  • Mostrar o que está acontecendo, com nome. A tela de sincronização diz a fase (enviando ou baixando) e a coleção em português — "Baixando clientes", "Baixando ordens de serviço". Quem espera sabendo o que espera não acha que o app morreu.

O resultado dessa soma, na Reticar: a primeira sincronização — a mais pesada, porque traz a carga inicial inteira — leva, em média, menos de 10 segundos para um vendedor típico, no aparelho Android do próprio cliente e em rede móvel. As seguintes são bem mais rápidas, porque só trazem o que mudou.

O que muda dentro do aplicativo#

Três mudanças estruturais, e nenhuma é visual.

A tela passa a ler do banco local. A lista não chama a API: a interface observa o banco do aparelho e se atualiza sozinha quando ele muda — porque o usuário criou algo ou porque a sincronização trouxe novidade. É o que faz a busca sobre milhares de registros ser instantânea, com ou sem rede.

A escrita vira duas etapas. O registro é gravado no banco local e enfileirado; a fila sobe quando há rede. Para o usuário, o cadastro terminou no instante em que ele salvou.

O registro nasce com identidade própria, gerada no aparelho antes de qualquer contato com o servidor. Sem isso, nada criado offline poderia ser referenciado por outro registro até o app conseguir perguntar "que número você deu para isso?".

Há uma decisão nossa com consequência direta no escopo. Usamos o RxDB como camada de dados reativa, e o armazenamento persistente oficial dele para SQLite é um plugin comercial — parte das licenças Premium, com versão de avaliação limitada a 500 documentos e sem índices, o que não serve para uma base de milhares de registros. Nossa saída foi rodar o RxDB em memória e manter, por conta própria, um espelho em SQLite no aparelho.

A consequência disso é a parte que interessa a quem contrata: a base sincronizada ocupa memória do aparelho. Decidir o que desce para o dispositivo deixa de ser só uma questão de tempo de download e vira orçamento de memória. É o que torna a próxima seção obrigatória em vez de recomendável.

O que muda no servidor#

Esta é a parte que costuma surpreender: a maior parte do trabalho de offline-first não está no aplicativo.

Uma API tradicional responde "me dê a lista de clientes". Um aplicativo offline pergunta outra coisa: "o que mudou desde a última vez que conversamos?" — e o servidor precisa entregar criações, alterações e exclusões desde um ponto de referência que o próprio app guarda.

Disso decorrem três exigências:

  • Exclusão passa a ser marcação, não remoção. Se o registro simplesmente sumir do banco, ele não aparece na lista de mudanças e o aplicativo nunca fica sabendo que precisa tirá-lo da tela do usuário.
  • A ordem importa. Registros que dependem de outros precisam subir e descer na sequência certa — a região antes do cliente, o cliente antes da visita.
  • Envio antes de recebimento. O aplicativo primeiro manda o que está na fila e só depois pergunta o que há de novo — na ordem inversa, a versão antiga do servidor volta por cima de uma alteração que ainda não subiu.

E há o recorte por permissão, que é a otimização mais subestimada do assunto. Na Reticar, o vendedor só recebe no aparelho o que ele tem direito de ver: as visitas em que é o responsável e os clientes das regiões a que está vinculado. A base tem 3.819 clientes; o que desce para cada celular é uma fração disso — o que melhora download, consumo de memória e segurança ao mesmo tempo, porque dado que não desce não vaza se o aparelho for perdido.

E o esforço merece ser dimensionado com honestidade: instrumentar cada entidade para participar da sincronização é trabalho manual. No projeto da Reticar, esse módulo do servidor passa de 1.300 linhas. Não é uma chave que se liga.

O que não vai para o aparelho#

Esta é a decisão que mais economiza dinheiro num projeto offline, e é de produto, não de engenharia. O critério não é a importância do dado — é se ele tem fim.

Tipo de dadoVai para o aparelho?Exemplo real
Catálogo e dado de referênciaSim, só leituraserviços, peças e regiões no app da Reticar; exercícios e alimentos no app da Team Garin
Dado operacional do usuário, limitadoSim, com ida e voltaa visita do vendedor; o perfil e o questionário do aluno
Histórico ilimitadoNãotreinos e dietas já realizados: a conclusão é enfileirada e enviada, mas o histórico é consultado na API quando o aluno pede
Dado que exige tempo real ou integraçãoNãoconsulta a sistema de terceiro, e o módulo de inteligência artificial do app de treino
Dado que não é do usuárioNão desceclientes de outras regiões, no app do vendedor

A linha do histórico é a que gera mais discussão em reunião de escopo, e é a mais fácil de defender: histórico cresce para sempre, e nada que cresce para sempre cabe num aparelho. Foi assim que definimos o escopo offline do aplicativo da consultoria esportiva Team Garin, hoje virando um produto SaaS: o aluno precisa registrar o treino de hoje sem sinal — ele não precisa carregar dois anos de treinos no bolso para isso.

O mesmo raciocínio, aplicado a volume, resolveu o app de campo do sistema de gestão genética da DGA Intelligence: o rebanho é grande demais para descer inteiro, então o aplicativo sincroniza apenas os animais com situação ativa, e o que sai desse conjunto é removido do aparelho na sincronização seguinte.

Também há o caso em que o offline precisa cobrir a operação inteira porque ela acontece, de fato, sem sinal: é o que fazemos no app de gestão de ativos e hardware da GT, cuja operação visitamos em campo para remodelar o aplicativo — o registro dessa visita está no YouTube.

Conflito, e o que acontece com a escrita que o servidor recusa#

Duas pessoas editam o mesmo registro sem sinal. Quando reconectam, o padrão mais comum — e o que usamos — é simples: a última alteração que chega ao servidor prevalece, sem mesclagem e sem aviso. Para cadastro e registro de campo, onde cada pessoa mexe no que é dela, basta. Para edição colaborativa do mesmo documento, não — e mesclar campo a campo custa bem mais, então a decisão pertence ao escopo.

Existe um segundo caso, menos discutido e mais incômodo: a escrita que o servidor recusa em definitivo. Um registro criado offline que fere uma regra de validação será rejeitado hoje, amanhã e sempre. Como a fila é ordenada, essa entrada trava tudo que está atrás dela.

A saída usual é descartar a entrada depois de um número de tentativas, para destravar o restante. Isso é razoável, e tem um efeito colateral que precisa ser dito em voz alta: o registro continua no aparelho marcado como não sincronizado, para sempre — sem explicação do motivo e sem caminho para resolver. No app da Reticar, cada ordem de serviço carrega esse estado num ícone próprio, sincronizada ou não; o que o ícone não conta é se ainda há esperança.

Não existe resposta única — existe decisão consciente. Avisar o usuário, mandar o registro para uma área de quarentena ou aceitar a perda são caminhos com custos diferentes; o erro é não escolher. Offline-first garante que a equipe consegue trabalhar sem sinal; não garante sozinho que tudo que foi digitado chegou.

Perguntas frequentes#

Offline-first é a mesma coisa que cache ou PWA?#

Não. Cache guarda a resposta de uma requisição que já aconteceu e serve para acelerar leitura. Offline-first é o aplicativo ter um banco de dados próprio no aparelho como fonte do que aparece na tela, incluindo o que o usuário cria sem sinal. O teste prático: em modo avião, um app com cache mostra o que já foi visto; um app offline-first deixa cadastrar algo novo, e esse registro sobrevive a fechar e reabrir o aplicativo.

Meu aplicativo já tem modo offline. Isso basta?#

Depende de como ele se comporta em conexão ruim, que é diferente de conexão ausente. Muitos apps com modo offline sincronizam tudo na abertura e bloqueiam a interface enquanto isso acontece — em rede lenta, o resultado é pior do que não ter offline. Os sinais de que não basta são: o app trava ao abrir, demora sem explicar o que está fazendo, ou não deixa claro se o que foi registrado já subiu.

Dá para adicionar offline depois que o aplicativo já está pronto?#

Dá, mas não é um ajuste no aplicativo: é uma mudança no servidor também. A API precisa passar a responder "o que mudou desde tal ponto", aceitar registros com identificador gerado pelo próprio aparelho e marcar exclusões em vez de apagar de fato. Por isso a conversa de offline começa pela equipe de backend, não pela de mobile.

Preciso de offline se minha equipe trabalha só em área urbana?#

Provavelmente não pelo motivo que você imagina, mas talvez sim por outro. O critério não é a cidade, é onde o trabalho acontece: subsolo, galpão, elevador, estacionamento e prédio industrial derrubam sinal dentro de capital. Se a pessoa usa o sistema sentada, com Wi-Fi, offline-first é custo sem retorno.

O que acontece se duas pessoas editarem o mesmo registro offline?#

No padrão mais comum, a última alteração que chega ao servidor prevalece, sem aviso e sem mesclagem. Isso é aceitável para cadastro e registro de campo, onde cada pessoa mexe no que é seu, e é insuficiente para edição colaborativa do mesmo documento. Vale decidir isso no escopo, porque a alternativa — mesclar alteração campo a campo — custa consideravelmente mais.

Fontes#

Próximo passo#

Se a sua equipe trabalha onde o sinal falha, o ponto de partida não é escolher tecnologia: é decidir o que precisa funcionar sem rede e o que não vai para o aparelho. Foi assim que substituímos o sistema comercial de campo da Reticar Motores — e é o tipo de decisão que tratamos em sistema sob medida.

Compartilhar

Continue por aqui

Mais sobre Decidir e comprar software sob medida

Contato

Vamos conversar sobre o seu projeto

Conte o que você precisa resolver. Retornamos rápido, com gente que entende de tecnologia e de negócio.

Prefere falar direto?

Escolha o canal que preferir. Respondemos rápido, no horário comercial.

Da primeira conversa ao go-live: eficiência, segurança e inovação.