Compartilhar via


Armazenar dados no dispositivo

As Aplicações Web Progressivas (PWA) oferecem opções robustas para armazenar dados localmente para permitir que os utilizadores continuem a trabalhar mesmo que a ligação de rede se torne instável ou fique offline.

Existem várias formas de um PWA armazenar dados num dispositivo, como o armazenamento local, a API de Cache ou o IndexedDB.

A tabela seguinte descreve as diferentes opções e o resto deste artigo vai para mais detalhes e cenários de utilização para cada opção.

Opção de armazenamento Descrição
Armazenamento Web O Armazenamento Web tem dois tipos: sessão e local. O Armazenamento Web é útil para armazenar pequenas quantidades de dados a partir do código de front-end da sua aplicação. Os dados são estruturados como pares chave-valor e só estão disponíveis para a origem atual da aplicação. No caso do armazenamento de sessões, os dados são limpos quando a sessão termina, por exemplo, quando a aplicação é fechada ou quando o utilizador navega para outra origem na mesma janela ou separador. O armazenamento local persiste até que a aplicação remova os dados.
IndexedDB IndexedDB é uma API para armazenar grandes quantidades de dados estruturados. A API é assíncrona e pode ser utilizada tanto a partir do código de front-end da sua aplicação como do código de trabalho de serviço. Utilize a API IndexedDB para armazenar uma quantidade significativa de dados estruturados no cliente ou dados binários, como ficheiros ou objetos de multimédia encriptados.
Cache A API de Cache pode ser utilizada para gerir recursos em cache. A API de Cache é baseada em Promessas e permite que os programadores armazenem e obtenham muitos recursos Web : HTML, CSS, JavaScript, imagens, JSON, etc. Normalmente, a API de Cache é utilizada no contexto de uma função de trabalho de serviço, mas também está disponível para o código de front-end da sua aplicação.
Acesso ao Sistema de Ficheiros A API de Acesso ao Sistema de Ficheiros permite que o PWA leia ficheiros e pastas no dispositivo do utilizador e guarde as alterações nos mesmos.

Nota: não utilize WebSQL ou Cache de Aplicações. Embora estes sejam outros dois mecanismos de armazenamento do browser, ambos foram preteridos. Em vez de WebSQL, utilize IndexedDB. Em vez da Cache da Aplicação, utilize a API de Cache.

Armazenamento Web

O Armazenamento Web é útil para armazenar pequenas quantidades de dados de cadeia no dispositivo do utilizador. A simplicidade do sistema de par chave-valor do Armazenamento Web facilita a utilização.

O Armazenamento Web funciona de forma síncrona apenas no thread principal da sua aplicação. Isto significa que o Armazenamento Web não está disponível para utilização nas funções de trabalho de serviço e que a utilização intensiva do Armazenamento Web pode criar problemas de desempenho para a sua aplicação.

Cada tipo de Armazenamento Web, sessão e local é mantido como um arquivo de dados separado que está isolado do domínio que o criou.

  • sessionStorage persiste apenas durante a sessão, por exemplo, enquanto o browser estiver aberto, o que inclui quando a página é atualizada.
  • localStorage persiste até que os dados sejam removidos pelo código da aplicação, pelo utilizador ou pelo browser.

O código seguinte mostra como utilizar localStorageo , que é semelhante ao sessionStorage que é utilizado:

const browserInformation = {
  name: 'Microsoft Edge',
  version: 108
};

localStorage.setItem('browser', JSON.stringify(browserInformation));

O código acima armazena um objeto JavaScript como uma cadeia JSON com localStorage o setItem() método e atribui uma chave igual a browser. Pode obter as informações através do localStoragegetItem() método conforme mostrado abaixo:

const value = localStorage.getItem('browser');

const browserInformation = JSON.parse(value);

Para saber mais, veja API de Armazenamento Web no MDN.

IndexedDB

O IndexedDB é uma API assíncrona para armazenar dados estruturados que podem ser utilizados no código de front-end ou no código de trabalho de serviço da sua aplicação. Utilize a API IndexedDB para armazenar uma quantidade significativa de dados estruturados no cliente ou dados binários, como ficheiros ou objetos de multimédia encriptados.

O IndexedDB é a melhor opção para armazenar dados no seu PWA, uma vez que a utilização da API não abranda a aplicação ao bloquear o thread principal e pode ser utilizada tanto a partir do código de front-end da sua aplicação como da função de trabalho de serviço.

A utilização do IndexedDB é mais complexa do que utilizar o Armazenamento Web e requer os seguintes passos para armazenar dados:

  1. Abra uma base de dados com a window.indexedDB.open() função .
  2. Crie um arquivo de objetos na base de dados com a IDBDatabase.createObjectStore() função .
  3. Inicie uma transação para armazenar dados com a IDBDatabase.transaction() função .
  4. Aguarde pela conclusão da operação ao ouvir um evento.

Para saber mais e ver exemplos de código, veja Using IndexedDB on MDN (Utilizar a IndexedDB na MDN).

Cache

A API de Cache é um sistema para armazenar e obter pedidos de rede e respostas no código de front-end ou na função de trabalho de serviço da sua aplicação. Pode ser utilizado para armazenar recursos, como imagens e ficheiros, localmente no dispositivo do utilizador. Isto pode fazer com que a sua aplicação funcione mesmo quando está offline ou melhorar o seu desempenho ao reduzir o número de pedidos de rede necessários para compor a aplicação.

O fragmento de código seguinte mostra como ouvir o fetch evento numa função de trabalho de serviço e armazenar a resposta do servidor com a API de Cache:

self.addEventListener("fetch", event => {
  async function cacheAndReturnRequest() {
    // Get the response from the server.
    const fetchResponse = await fetch(event.request.url);
    // Open the app's cache.
    const cache = await caches.open("cache-name");
    // Put the response in cache.
    cache.put(event.request.url, fetchResponse.clone());
    // And return the response.
    return fetchResponse.
  }

  event.respondWith(cacheAndReturnRequest());
});

Para descobrir outros cenários úteis da API de Cache, veja Utilizar uma função de trabalho de serviço para gerir pedidos de rede.

Acesso ao Sistema de Ficheiros

A API de Acesso ao Sistema de Ficheiros permite que a sua aplicação aceda a ficheiros no dispositivo do utilizador de uma forma semelhante às aplicações nativas. Pode ser utilizado para criar aplicações que podem ler e escrever ficheiros, como editores de texto ou imagens.

Para abrir um ficheiro a partir do dispositivo do utilizador, utilize a showOpenFilePicker() função :

openFileButton.addEventListener("click", async () => {
  const fileHandles = await window.showOpenFilePicker();
});

Para saber mais, veja Window.showOpenFilePicker() no MDN.

A API de Acesso ao Sistema de Ficheiros também pode ser associada à funcionalidade Processamento de Ficheiros PWA para registar a sua aplicação como um processador de tipos de ficheiros específicos e, por conseguinte, sentir-se mais nativa dos utilizadores. Para saber mais, consulte Processar ficheiros em Aplicações Web Progressivas.

A API de Acesso ao Sistema de Ficheiros privado de origem é uma variação da API de Acesso ao Sistema de Ficheiros que se destina a fornecer mais privacidade aos utilizadores. Também permite que as aplicações acedam a ficheiros no dispositivo do utilizador, mas apenas dentro de um diretório específico que seja privado à origem da aplicação. Além disso, esta API não se destina a facilitar o acesso dos utilizadores ao diretório privado com o respetivo explorador de ficheiros.

Para abrir um ficheiro a partir do sistema de ficheiros origin-private, utilize a navigator.storage API baseada em Promessas:

// Get the origin-private directory handle.
const root = await navigator.storage.getDirectory();
// Get the handle for a file in the directory.
const fileHandle = await root.getFileHandle("my-file.txt");

Cota de Armazenamento

No Microsoft Edge, o armazenamento local e de sessão está limitado a cerca de 5 MB cada.

Outros tipos de armazenamento de dados, como IndexedDB, API de Cache ou API de Acesso ao Sistema de Ficheiros Privados de Origem, podem utilizar até 60% do espaço total em disco no dispositivo. Por exemplo, se o dispositivo em que a sua aplicação está a ser executada tiver um disco de 64 GB, o Microsoft Edge permite que a sua aplicação armazene até cerca de 38 GB de dados.

Tenha em atenção que o espaço livre realmente disponível no dispositivo pode ser inferior à quota de armazenamento de 60%. Por exemplo, se o dispositivo em que a aplicação está a ser executada tiver um disco de 64 GB, mas 50 GB já estiver a ser utilizado pelo sistema operativo e outros ficheiros, a sua aplicação só poderá armazenar 14 GB de dados, mesmo que a quota de armazenamento ainda seja de 38 GB.

Pode utilizar navigator.storage.estimate() para perguntar à API do Gestor de Armazenamento qual é a quota de armazenamento da origem da sua aplicação e quanto da mesma já está a ser utilizada. Para saber mais, veja StorageManager.estimate() no MDN.

Tentar armazenar mais dados do que os disponíveis ou permitidos resulta num erro de JavaScript. O código deve detetar este erro através try...catch de instruções. O fragmento de código abaixo mostra como detetar um erro de quota excedida ao armazenar dados com o Armazenamento Web:

try {
  localStorage.setItem('foo', 'bar');
} catch (e) {
  // Code that handles the lack of storage space.
}

Expulsão de dados

Quando o dispositivo do utilizador começa a ter pouco espaço em disco disponível, também conhecido como pressão de armazenamento, o Microsoft Edge começará a expulsar dados não persistentes.

Isto significa que os dados armazenados pela aplicação com a API de Cache, o IndexedDB, a API de Acesso ao Sistema de Ficheiros Privado de Origem ou o Armazenamento Web podem ser expulsos.

Por predefinição, os dados que a sua aplicação armazena não são considerados persistentes e podem ser expulsos quando há pressão de armazenamento. Se a sua aplicação armazenar dados críticos, utilize a função para tornar o navigator.storage.persist() armazenamento da sua aplicação persistente. O armazenamento persistente só pode ser limpo pelo utilizador. Para saber mais, veja StorageManager.persist() no MDN.