Dados Off-line em PWA

PWA
Tempo de leitura: 4 minutos

Dados Off-line em PWA: Para que um Progressive Web App (PWA) seja verdadeiramente confiável (reliable), ele precisa não apenas do App Shell estático (CSS, JS) em cache, mas também da capacidade de armazenar e gerenciar dados dinâmicos para o modo offline. É aqui que entra o IndexedDB.

O IndexedDB é uma API de armazenamento no lado do cliente que funciona como um banco de dados NoSQL embutido no navegador. Ele é ideal para grandes volumes de dados estruturados, fornecendo a base para o funcionamento completo de um PWA, mesmo sem conectividade.

1. 🆚 IndexedDB vs. Outras APIs de Armazenamento

Embora existam outras APIs, o IndexedDB é a escolha padrão para PWAs focados em dados complexos:

APIModeloCapacidade de ArmazenamentoTipo de OperaçãoIdeal Para…
IndexedDBObjeto/ChaveGigabytes (Alto)Assíncrona (Promises)Dados Estruturados, Aplicações complexas.
Local StorageChave-ValorKilobytes (Baixo)SíncronaPreferências de usuário, Tokens simples.
Cache APIRequest-ResponseAltoAssíncrona (Promises)Arquivos estáticos (Assets).

Foco: IndexedDB é o único que oferece a capacidade, o modelo de dados e a natureza assíncrona necessários para armazenar um catálogo de produtos ou um histórico de mensagens.

2. 🏛️ Estrutura do IndexedDB

A arquitetura do IndexedDB segue um modelo semelhante ao de bancos de dados:

  1. Banco de Dados (Database): O contêiner principal (ex: 'meu-app-db'). É aberto por versão.
  2. Object Stores (ObjectStore): Onde os dados são realmente armazenados, semelhante a tabelas em um banco relacional (ex: 'usuarios', 'produtos').
  3. Índices (Indexes): Usados para acelerar a busca de dados que não sejam pela chave primária.
  4. Transações (Transactions): Garantem que as operações (leitura/escrita) sejam atômicas, mantendo a integridade dos dados.

3. ⚙️ Operações Básicas (Sintaxe Moderna com Promises)

O IndexedDB é baseado em requisições (request.onsuccess, request.onerror), que são naturalmente assíncronas. Bibliotecas externas (como Dexie.js) ou funções wrapper são frequentemente usadas para convertê-lo em sintaxe moderna baseada em Promise/async/await.

A. Criando e Abrindo o Banco de Dados

O onupgradeneeded é o único local onde você pode criar ou alterar a estrutura do banco (Object Stores). Ele é chamado se a versão fornecida (1) for maior que a versão atual do banco de dados do navegador.

JavaScript

const DB_NAME = 'meu-pwa-db';
const STORE_NAME = 'produtos';

const openDB = () => {
  return new Promise((resolve, reject) => {
    const request = window.indexedDB.open(DB_NAME, 1);

    request.onerror = (event) => reject('Erro ao abrir DB.');
    
    request.onsuccess = (event) => resolve(event.target.result);

    request.onupgradeneeded = (event) => {
      const db = event.target.result;
      // Cria a Object Store, definindo 'id' como chave primária
      db.createObjectStore(STORE_NAME, { keyPath: 'id' }); 
    };
  });
};

B. Escrevendo Dados (Adicionar/Atualizar)

Todas as operações de escrita precisam de uma Transação no modo 'readwrite'.

JavaScript

// Exemplo de como adicionar/atualizar dados (put)
async function putData(data) {
  const db = await openDB();
  // Inicia a transação de leitura/escrita
  const transaction = db.transaction(STORE_NAME, 'readwrite');
  const store = transaction.objectStore(STORE_NAME);

  return new Promise((resolve, reject) => {
    const request = store.put(data);
    
    request.onsuccess = () => resolve('Dado salvo com sucesso.');
    request.onerror = (event) => reject(event.target.error);

    // Opcional: Garante que a Promise só resolva após a transação ser concluída
    transaction.oncomplete = resolve; 
  });
}

C. Lendo Dados (Busca por Chave)

A leitura requer uma transação no modo padrão 'readonly'.

JavaScript

// Exemplo de busca de dados por chave primária (id)
async function getDataById(id) {
  const db = await openDB();
  const transaction = db.transaction(STORE_NAME, 'readonly');
  const store = transaction.objectStore(STORE_NAME);

  return new Promise((resolve, reject) => {
    const request = store.get(id);

    request.onsuccess = (event) => resolve(event.target.result);
    request.onerror = (event) => reject(event.target.error);
  });
}

✅ Conclusão

Dados Off-line em PWA: O IndexedDB é a solução fundamental para a persistência de grandes volumes de dados estruturados em PWAs. Ao contrário do Local Storage, ele é assíncrono e robusto, sendo a tecnologia ideal para construir a camada de dados offline da sua aplicação. Dominar a criação do Banco de Dados, Object Stores e o uso de Transações permite que você crie experiências de usuário que permanecem ricas e funcionais, mesmo quando a conexão com a internet falha.

Toda jornada tem um início, e o início para se tornar um desenvolvedor web é dominar as seguintes tecnologias, que você encontra aqui mesmo:

HTML
HTML
CSS
CSS
Javascript
JavaScript

E se você gosta do nosso conteúdo, não deixe de contribuir adquirindo os serviços e produtos dos nossos apoiadores e empresas que somos associados:

Hospedagem Hostinger
Ofertas Amazon
Amazon Prime

Author: Thiago Rossi
Com mais de 20 anos de experiência em tecnologia, atuo como Engenheiro de Computação, desenvolvedor de sistemas, escritor e produtor de conteúdo. Minha trajetória passa pelo ensino técnico, desenvolvimento web, arquitetura de sistemas e criação de soluções voltadas para a indústria de jogos digitais. Acredito que conhecimento deve ser acessível e aplicável. Essa visão resultou em uma biblioteca com mais de 550 artigos gratuitos, abrangendo temas como desenvolvimento web, infraestrutura, inteligência artificial, Game Design, mercado de jogos e carreiras na indústria de games. Sou autor do livro "GDD – O Guia Definitivo", uma obra dedicada ao planejamento e documentação de jogos digitais, e criador do GameMeTRix, uma plataforma que auxilia desenvolvedores na análise e validação de ideias para jogos. Meu trabalho busca conectar planejamento, tecnologia e mercado para ajudar criadores a transformar boas ideias em projetos viáveis. Atualmente concentro meus estudos e projetos no desenvolvimento de jogos web, na criação de metodologias para validação de produtos digitais e na produção de conteúdo técnico voltado ao ecossistema de jogos. Meu compromisso é unir teoria, prática e experiência de mercado para contribuir com o crescimento de novos desenvolvedores e profissionais da área.