PWA vs App Nativo: Por Que Progressive Web Apps São o Futuro do SaaS Mobile
Para plataformas SaaS B2B, a pergunta "preciso de um app nativo?" surge cedo. A resposta, na maioria dos casos, é não — e um PWA bem implementado entrega 90% dos benefícios com 10% do custo.
O Que É um Progressive Web App
Um PWA é uma aplicação web que usa APIs modernas do browser para se comportar como um app nativo:
- Instalável: aparece na tela inicial sem passar pela App Store
- Offline: funciona sem conexão com cache inteligente
- Push Notifications: notificações nativas mesmo com o browser fechado
- Standalone Mode: abre sem barra de endereços, como um app
- Performance: carregamento rápido via caching de assets
PWA vs Nativo: A Comparação Honesta
Custo de Desenvolvimento
| | PWA | iOS Nativo | Android Nativo | React Native | |--|-----|-----------|----------------|--------------| | Tempo inicial | 1-2 dias | 3-6 meses | 3-6 meses | 2-4 meses | | Manutenção | 1 codebase | Separado | Separado | Parcialmente compartilhado | | Update deploy | Imediato | App Store review (1-7 dias) | Play Store (horas) | Dependente |
Funcionalidades
| | PWA | App Nativo | |--|-----|-----------| | Push Notifications | ✅ (Web Push API) | ✅ | | Acesso à câmera | ✅ | ✅ | | Geolocalização | ✅ | ✅ | | Modo offline | ✅ (Service Worker) | ✅ | | Bluetooth/NFC | Parcial | ✅ | | Background sync | ✅ | ✅ | | Face ID / Biometria | ✅ (WebAuthn) | ✅ | | Acesso a arquivos | Parcial | ✅ |
Quando o App Nativo Ainda Faz Sentido
- Jogos com gráficos intensivos
- Apps de câmera/foto com filtros em tempo real
- Acesso a hardware específico (Bluetooth LE, NFC intensivo)
- Monetização via In-App Purchase da App Store
- Apps que precisam rodar em background pesado
Quando PWA É a Escolha Certa (SaaS B2B)
Para dashboards, CRMs, plataformas de automação e ferramentas de produtividade:
- Usuários acessam via browser mesmo no desktop
- O app é uma extensão do produto web
- Você quer um único codebase
- Updates precisam ser instantâneos
Implementando PWA em Next.js 16 sem next-pwa
A maioria dos tutoriais usa next-pwa, mas você pode implementar tudo manualmente com controle total.
1. manifest.json
{
"name": "Sofia AI",
"short_name": "Sofia AI",
"description": "Plataforma de Orquestração de Agentes IA",
"start_url": "/dashboard",
"display": "standalone",
"background_color": "#0a0a0f",
"theme_color": "#7c3aed",
"icons": [
{ "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
]
}
2. Service Worker Manual
// public/sw.js
const CACHE_NAME = 'sofia-ai-v1'
const STATIC_ASSETS = ['/', '/dashboard', '/offline']
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => cache.addAll(STATIC_ASSETS))
)
self.skipWaiting()
})
self.addEventListener('fetch', (event) => {
if (event.request.mode === 'navigate') {
event.respondWith(
fetch(event.request).catch(() => caches.match('/offline'))
)
return
}
// Cache First para assets estáticos
if (event.request.url.match(/\.(js|css|png|svg|jpg)$/)) {
event.respondWith(
caches.match(event.request).then((cached) => {
return cached || fetch(event.request).then((response) => {
caches.open(CACHE_NAME).then((cache) => cache.put(event.request, response.clone()))
return response
})
})
)
}
})
3. Registrador Client-Side
// src/components/sofia/ServiceWorkerRegistrar.tsx
'use client'
import { useEffect } from 'react'
export function ServiceWorkerRegistrar() {
useEffect(() => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js').catch(() => {})
}
}, [])
return null
}
4. Meta Tags no Layout
// src/app/layout.tsx
<link rel="manifest" href="/manifest.json" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Sofia AI" />
<meta name="theme-color" content="#7c3aed" />
5. Botão de Instalação
// src/components/sofia/InstallPWA.tsx
'use client'
import { useState, useEffect } from 'react'
import { Button } from '@/components/ui/button'
import { Download } from 'lucide-react'
interface BeforeInstallPromptEvent extends Event {
prompt: () => Promise<void>
userChoice: Promise<{ outcome: 'accepted' | 'dismissed' }>
}
export function InstallPWA() {
const [installPrompt, setInstallPrompt] = useState<BeforeInstallPromptEvent | null>(null)
useEffect(() => {
window.addEventListener('beforeinstallprompt', (e) => {
e.preventDefault()
setInstallPrompt(e as BeforeInstallPromptEvent)
})
}, [])
if (!installPrompt) return null
return (
<Button
size="sm"
variant="outline"
onClick={async () => {
await installPrompt.prompt()
setInstallPrompt(null)
}}
>
<Download className="h-3 w-3 mr-2" />
Instalar App
</Button>
)
}
Push Notifications com Web Push API
Web Push permite notificações mesmo com o browser fechado:
// Solicitar permissão
const permission = await Notification.requestPermission()
// Assinar o push service
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY,
})
// Enviar subscription ao servidor
await fetch('/api/push/subscribe', {
method: 'POST',
body: JSON.stringify(subscription),
})
No service worker:
self.addEventListener('push', (event) => {
const data = event.data.json()
self.registration.showNotification(data.title, {
body: data.body,
icon: '/icons/icon-192.png',
})
})
Métricas de PWA: Core Web Vitals
Para que o PWA seja aprovado pelo Google para instalação:
- LCP (Largest Contentful Paint): < 2.5s
- FID (First Input Delay): < 100ms
- CLS (Cumulative Layout Shift): < 0.1
Ferramentas: lighthouse, Chrome DevTools → Application → Manifest.
A Decisão na Sofia AI
Implementamos PWA no Sprint 18 sem next-pwa por razões simples:
- Controle total sobre a estratégia de cache
- Sem dependência extra que pode quebrar com updates do Next.js
- O service worker manual é simples e legível
- Funciona perfeitamente com App Router do Next.js 16
A implementação levou 1 dia. Para um app nativo equivalente: meses.
Conclusão
Para SaaS B2B com dashboard e ferramentas de produtividade, PWA é a escolha correta. O ROI é incomparável — uma fração do custo de desenvolvimento, zero processo de aprovação de App Store, updates instantâneos.
O único cenário em que recomendo app nativo para SaaS B2B é quando o produto principal é genuinamente mobile-first (field service, delivery, inspeções presenciais) ou quando a distribuição via App Store é estratégica para discovery.
Para tudo mais: PWA first.
Implemente agora: