Uma PWA é um app web que usa service workers, manifest e HTTPS para ser instalável, funcionar offline e receber notificações push. Cunhado por Alex Russell e Frances Berriman em 2015, o termo fecha a distância entre um site e um app instalado sem sair da web: um único código-fonte, ícone na tela inicial, janela própria e uma tela que continua funcionando quando o trem entra no túnel. O ângulo que este glossário acrescenta — e que os guias de frontend pulam: uma PWA continua sendo um cliente — o service worker faz cache, mas o seu backend é a fonte da verdade.
Principais pontos
| Pergunta | Resposta |
|---|---|
| Os três pilares | Service worker · web app manifest · HTTPS |
| O que ela adiciona | Instalável · funciona offline · recebe push — sobre um único código-fonte |
| vs. site responsivo | Adiciona service worker + manifest; layout sozinho não faz uma PWA |
| vs. nativo | Alcance e velocidade vs. acesso ao hardware e presença na loja |
| A verdade do backend | O cache do SW espelha; a API/BaaS é quem manda |
Os três pilares, e o backend por trás deles
// JavaScript — the PWA's three pillars + the backend behind them
// 1 · Service worker: caches the shell, buffers writes when offline
navigator.serviceWorker.register('/sw.js');
// 2 · Manifest (public/manifest.json) makes it installable:
// { "name": "Notes", "display": "standalone", "start_url": "/", "icons": [...] }
// 3 · HTTPS is required — service workers refuse to run otherwise.
// The catch: the SW cache is a MIRROR, not the source of truth.
// When back online, queued writes sync to the real backend:
const note = new Parse.Object('Note').set('text', draft);
await note.save(); // the BaaS is authoritative; the cache was a buffer // Flutter / Dart — Back4app Flutter SDK (Flutter web compiles to a PWA)
// The service worker caches the app shell; data still lives on the backend.
final note = ParseObject('Note')..set('text', draft);
await note.save();
// Offline-first pattern: write locally, queue, and sync when connectivity
// returns — the API/BaaS is the source of truth, the cache is a local mirror.
// Push notifications need a BACKEND to send them; the client only subscribes. // Swift — a native shell can host a PWA/WebView; the backend is shared
// The point of parity: whatever the client (PWA, native, web), the
// source of truth is the same backend API.
var note = Note()
note.text = draft
_ = try await note.save()
// Offline-first: cache locally, sync when online — the API is authoritative.
// Web push (PWA) and native push (APNs) both need a backend to SEND them. // Kotlin — a native shell can host a PWA/WebView; the backend is shared
// The point of parity: whatever the client (PWA, native, web), the
// source of truth is the same backend API.
val note = ParseObject("Note")
note.put("text", draft)
note.save()
// Offline-first: cache locally, sync when online — the API is authoritative.
// Web push (PWA) and native push (APNs/FCM) both need a backend to SEND them. Um service worker é um script em segundo plano que fica entre o app e a rede como um proxy — ele cacheia o shell e o serve offline; um web app manifest é o arquivo de metadados JSON (nome, ícones, display: standalone, URL inicial) que torna o app instalável; e HTTPS é obrigatório, porque service workers se recusam a rodar fora de um contexto seguro. Esses três fazem a frente do app. O save() nas abas de código mostra o que fica atrás dela: o cache é um espelho, e quando a rede volta, a escrita sincroniza com o backend autoritativo.
Como uma PWA serve uma página offline
Estratégias de cache offline
| Estratégia | Serve de | Ideal para |
|---|---|---|
| Cache-first | Cache, depois rede | Assets estáticos — shell, ícones, fontes |
| Network-first | Rede, com fallback no cache | Dados frescos que precisam estar atuais |
| Stale-while-revalidate | Cache agora, atualiza em segundo plano | Conteúdo que pode ficar um instante desatualizado |
| Cache-only / network-only | Uma fonte só | Essenciais pré-cacheados / chamadas que nunca cacheiam |
A decisão é por recurso, não por app: o shell do app quer cache-first para carregar na hora; os dados vivos do usuário querem network-first para frescor; um feed aceita stale-while-revalidate para parecer instantâneo e se corrigir sozinho. Seja qual for a escolha, o cache é um buffer de leitura/escrita sobre a API — escritas offline entram na fila local e se reconciliam ao reconectar, a mesma disciplina de catch-up que qualquer cliente offline-first precisa ter.
De onde as notificações push realmente vêm
O mecanismo que quase nenhum glossário explica, e o motivo pelo qual uma PWA precisa de um backend até para notificar. O cliente apenas se inscreve: pede permissão e recebe um endpoint de assinatura. Enviar é trabalho de servidor — seu backend → o serviço de push do navegador → o evento push do service worker → uma notificação exibida. O service worker pode acordar para exibi-la com o app fechado, mas nada chega se um backend não tiver enviado — e é por isso que “PWA tem push” é só metade de uma funcionalidade sem a metade servidor. O verbete de notificações push cobre a cadeia de entrega; o ponto aqui é que tanto o web push quanto o push nativo terminam no seu código decidindo enviar.
PWA vs. app nativo
| PWA | Nativo | |
|---|---|---|
| Código-fonte | Um, na web | Um por plataforma (ou multiplataforma) |
| Distribuição | Uma URL — sem loja | Lojas de aplicativos, com revisão |
| Atualizações | Instantâneas, do lado do servidor | Ciclo de release da loja |
| Descobribilidade | Indexada pela busca | Só a busca da loja |
| Acesso ao hardware | Limitado (varia por SO) | Completo |
| Confiabilidade do push | Boa no Android, restrita no iOS | Confiável via APNs/FCM |
| Realidade no iOS | Instalação só pelo Safari, push desde o 16.4 | Cidadão de primeira classe |
A assimetria honesta mora na última linha: o iOS é onde as PWAs são mais fracas — instalação apenas pelo Safari, nenhum prompt de instalação automático, push só com o app instalado e só em versões recentes, e sincronização em segundo plano incompleta. No Android e no desktop a distância para o nativo é pequena; no iOS ela é o fator decisivo para muitos produtos.
Casos de uso comuns
- Conteúdo e comércio — alcance, SEO e baixa fricção de instalação valem mais que um download de loja para conquistar usuários novos.
- Ferramentas internas — apps instaláveis e tolerantes a offline para usuários conhecidos, sem distribuição por loja.
- Apps de campo offline-first — capture dados sem sinal, sincronize quando ele volta; o padrão do cache como buffer.
- Alcance multiplataforma com orçamento curto — um código-fonte web cobrindo plataformas que um build nativo triplicaria.
- Companheira de um app nativo — o mesmo backend servindo uma PWA para alcance e um app nativo para profundidade.
Você deveria construir uma PWA? Matriz de decisão
| Situação | Tendência |
|---|---|
| Alcance, SEO, baixa fricção, um código-fonte | PWA |
| Audiência principal em Android/desktop | PWA — a distância para o nativo é pequena |
| iOS crítico com forte dependência de push | Nativo, ou aceite as ressalvas do iOS |
| Gráficos pesados, AR, hardware profundo | Nativo |
| Captura de dados offline-first | PWA com um backend de sincronização |
| Precisa de presença na loja | Nativo (ou PWA na loja, onde aceitam) |
Limitações e trade-offs
- O iOS limita o teto. Instalação só pelo Safari, push restrito e lacunas de sincronização em segundo plano fazem do iOS a restrição que mais decide o duelo PWA-versus-nativo.
- Acesso ao hardware é parcial. Bluetooth, NFC, contatos e APIs avançadas de câmera são limitados ou ausentes dependendo do SO — apps que mergulham no dispositivo ainda pedem nativo.
- O cache não é o banco de dados. Tratar o cache do service worker como fonte da verdade convida escritas perdidas e conflitos de dados velhos; ele é um buffer sobre o backend autoritativo.
- Push é metade cliente, metade servidor. Inscrever-se é fácil; a PWA ainda precisa de um backend para enviar, então “offline e push” é uma funcionalidade de backend usando crachá de frontend.
- Descobribilidade corta dos dois lados. Sem o pedágio da loja também não há a vitrine da loja; você troca curadoria e cerimônia de instalação por uma URL.
PWAs no Back4app
O Back4app é uma plataforma open-source de Backend as a Service (BaaS) que combina banco de dados gerenciado, APIs REST e GraphQL geradas automaticamente, autenticação, armazenamento de arquivos e funções serverless com Cloud Code. Ele é a metade backend da funcionalidade que os pilares de frontend apenas completam: o service worker cacheia o shell, mas o Back4app é a fonte da verdade que o cache espelha — usuários autenticados, dados sincronizados reconciliando escritas offline ao reconectar, e o servidor que de fato envia o web push ao qual uma PWA só consegue se inscrever. Como um único backend serve igualmente uma PWA, um app web comum e um app nativo por meio de SDKs por plataforma, o alcance multiplataforma que a PWA promete no frontend encontra o alcance escreva-uma-vez no backend — o cliente cacheia, a plataforma lembra, e as duas metades de “instalável, offline e push” finalmente se encontram.
Perguntas frequentes
O que é uma PWA?
Um app construído com tecnologias web padrão que usa capacidades modernas do navegador para se comportar como um app instalado — ícone na tela inicial, janela própria, suporte offline e notificações push — tudo a partir de um único código-fonte entregue pela web. O termo foi cunhado por Alex Russell e Frances Berriman em 2015.
O que torna um app uma PWA?
Três peças trabalhando juntas: um service worker (script em segundo plano que faz cache dos assets e habilita offline e push), um web app manifest (metadados JSON que tornam o app instalável) e HTTPS (service workers se recusam a rodar fora de um contexto seguro). Na prática, a régua é: instalável e confiável independentemente da rede.
O que é um service worker?
Um arquivo JavaScript que roda em segundo plano, na própria thread, atuando como proxy de rede entre o app e a internet. Ele intercepta requisições e as responde a partir do cache ou da rede — é isso que habilita uso offline, sincronização em segundo plano e o recebimento de mensagens push mesmo com o app fechado.
PWA ou app nativo: qual é melhor?
Uma PWA é mais rápida e barata de construir, usa um só código-fonte, atualiza na hora, dispensa loja de aplicativos e aparece na busca. Um app nativo tem acesso completo ao hardware, a UX mais fluida, push mais confiável e presença na loja. Escolha nativo para gráficos pesados ou integração profunda com o dispositivo; PWA para alcance e velocidade de lançamento.
Qual a diferença entre PWA e site responsivo?
Um site responsivo só adapta o layout ao tamanho da tela e depende de conexão. Uma PWA adiciona por cima instalação, cache offline e notificações push. Toda PWA é responsiva, mas um site responsivo só vira PWA quando ganha um service worker e um manifest.
PWA envia notificações push?
Ela recebe web push via as APIs Push e Notification, mas o cliente apenas se inscreve — quem envia de fato é um backend. No iOS o suporte chegou na versão 16.4 e só funciona com a PWA instalada na tela inicial, então o web push alcança um público mais restrito que o push nativo.
PWA funciona offline?
Sim — o service worker guarda assets e dados em cache e os serve quando a rede some. As estratégias comuns são cache-first para assets estáticos, network-first para dados que precisam estar frescos e stale-while-revalidate para exibição instantânea com atualização em segundo plano. Escritas feitas offline entram numa fila e sincronizam quando a conexão volta.
Dá para publicar uma PWA nas lojas de aplicativos?
Em parte. A loja do Android aceita PWAs empacotadas como trusted web activities, e algumas lojas de desktop as tratam como cidadãs de primeira classe. A App Store da Apple, na prática, não — PWAs que são sites reempacotados costumam ser rejeitadas — o que ajuda a explicar por que o iOS segue sendo a plataforma mais difícil para PWAs.