Há muitas opções diferentes para armazenar dados no navegador. Qual é a melhor para suas necessidades?
As conexões com a Internet podem ser instáveis ou inexistentes quando você está indo de um lugar para outro. suporte off-line e desempenho confiável são recursos comuns em Progressive Web Apps. Mesmo com a tecnologia sem fio perfeita ambientes, o uso criterioso de armazenamento em cache e outras técnicas de armazenamento pode melhorar substancialmente a experiência do usuário. Há várias maneiras de armazenar em cache seus recursos estáticos de aplicativo (HTML, JavaScript, CSS, imagens etc.) e (dados de usuários, artigos de notícias etc.). Mas qual é a melhor solução? Como quanto é possível armazenar? Como evitar a remoção?
O que devo usar?
Confira uma recomendação geral para armazenar recursos:
- Para os recursos de rede necessários para carregar seu app e conteúdo baseado em arquivos, use a API Cache Storage (parte service workers).
- Para outros dados, use IndexedDB (com um wrapper de promessas).
O IndexedDB e a API Cache Storage são compatíveis com todos os navegadores mais recentes.
Ambos são assíncronos e não bloqueiam a linha de execução principal. São
acessíveis do objeto window
, web workers e service workers, tornando
o que facilita o uso delas em qualquer parte do código.
E os outros mecanismos de armazenamento?
Há vários outros mecanismos de armazenamento disponíveis no navegador, mas eles têm uso limitado e podem causar problemas significativos de desempenho.
SessionStorage é específico por guia e tem escopo para vida útil da guia. Pode ser útil para armazenar pequenas quantidades de informações específicas, por exemplo, uma chave IndexedDB. Ele deve ser usado com cuidado, porque ela é síncrona e vai bloquear a linha de execução principal. É limitado a cerca de 5 MB e pode conter apenas strings. Como ele é específico para guias, ela não seja acessível por web workers ou service workers.
LocalStorage precisa ser evitado porque é síncrono e bloqueará a linha de execução principal. Ele tem um limite de cerca de 5 MB e pode conter somente strings. LocalStorage não pode ser acessado por web workers ou serviços trabalhadores
Os cookies têm suas finalidades, mas não devem ser usados para armazenamento. Os cookies são enviados com cada solicitação HTTP. Portanto, ao armazenar algo mais uma pequena quantidade de dados aumentará significativamente o tamanho de cada solicitação da Web. Elas são síncronas e não podem ser acessadas por web workers. Gostei LocalStorage e SessionStorage, os cookies são limitados apenas a strings.
A API File System e a API FileWriter oferecem métodos para leitura e gravação de arquivos em um sistema de arquivos em sandbox. Embora seja assíncrono, não é recomendado, porque é disponível apenas em navegadores baseados no Chromium.
A API File System Access foi criada para torná-la a leitura e a edição de arquivos em seu sistema de arquivos local. O usuário precisa conceder permissão antes que uma página possa ler ou gravar em qualquer arquivo local, e as permissões não são mantidas entre as sessões.
O WebSQL não deve ser usado, e o uso atual precisa ser migrado para IndexedDB. O suporte foi removido de quase todas as principais navegadores da Web. O W3C deixou de manter a especificação do Web SQL em 2010, sem planos de outras atualizações planejadas.
O cache do aplicativo não deve ser usado, e o uso atual deve ser migrados para service workers e para a API Cache. Foi descontinuado, e o suporte será removido dos navegadores em no futuro.
Quantos dados posso armazenar?
Resumindo, muitos, pelo menos algumas centenas de megabytes e potencialmente centenas de gigabytes ou mais. As implementações dos navegadores variam, mas a quantidade de armazenamento disponível geralmente se baseia na quantidade de armazenamento disponível no dispositivo.
- O Chrome permite que o navegador use até 80% do espaço total em disco. Uma origem pode
usam até 60% do espaço total em disco. É possível usar a classe StorageManager
API para determinar a cota máxima disponível. Outros apps baseados no Chromium
navegadores podem ser diferentes.
- No modo de navegação anônima, o Chrome reduz o armazenamento que uma origem pode usar a cerca de 5% do espaço total em disco.
- Se o usuário tiver ativado a opção "Limpar cookies e dados do site ao fechar todos janelas" no Chrome, a cota de armazenamento é reduzida significativamente máximo de aproximadamente 300 MB.
- Consulte a PR no 3896 para detalhes sobre a implementação do Chrome.
- O Internet Explorer 10 e posterior pode armazenar até 250 MB e fará com que o quando mais de 10 MB tiverem sido usados.
- O Firefox permite que o navegador use até 50% do espaço livre em disco. Um
eTLD+1
grupo (por exemplo,
example.com
,www.example.com
efoo.bar.example.com
) podem usar até 2 GB. Você pode usar o API StorageManager para determinar quanto espaço ainda há disponíveis. - O Safari (para computador e dispositivo móvel) parece permitir cerca de 1 GB. Quando o limite
for atingido, o Safari solicitará ao usuário, aumentando o limite em 200 MB
incrementos. Não encontrei nenhum documento oficial sobre isso.
- Se um PWA for adicionado à tela inicial no Safari para dispositivos móveis, ele parecerá criar um novo contêiner de armazenamento e nada será compartilhado entre o PWA e Safari para dispositivos móveis. Quando a cota de um PWA instalado for atingida, não parece ser nenhuma maneira de solicitar armazenamento adicional.
Antes, se um site excedesse um determinado limite de dados armazenados, o navegador solicita que o usuário conceda permissão para usar mais dados. Para Por exemplo, se a origem usar mais de 50 MB, o navegador pedirá que o usuário para armazenar até 100 MB e, em seguida, pedir novamente a cada 50 MB.
Atualmente, a maioria dos navegadores modernos não solicita ao usuário e permite que um site usar toda a cota atribuída. A exceção parece ser o Safari, que avisa quando a cota de armazenamento é excedida, solicitando permissão para aumentar a cota alocada. Se uma origem usar mais do que a cota alocada, outras tentativas de gravar dados vai falhar.
Como posso verificar a quantidade de armazenamento disponível?
Em muitos navegadores, você pode usar o API StorageManager para determinar a quantidade de armazenamento para a origem e a quantidade de armazenamento utilizada. Informa o total de bytes usados pelo IndexedDB e pela Cache API e possibilita para calcular o espaço de armazenamento restante aproximado.
if (navigator.storage && navigator.storage.estimate) {
const quota = await navigator.storage.estimate();
// quota.usage -> Number of bytes used.
// quota.quota -> Maximum number of bytes available.
const percentageUsed = (quota.usage / quota.quota) * 100;
console.log(`You've used ${percentageUsed}% of the available storage.`);
const remaining = quota.quota - quota.usage;
console.log(`You can write up to ${remaining} more bytes.`);
}
O StorageManager ainda não está implemented em todos os navegadores. precisa detectá-lo antes de usá-lo. Mesmo quando está disponível, você precisa ainda detectam erros de cota ultrapassada (veja abaixo). Em alguns casos, é possível a cota disponível para exceder a quantidade real de armazenamento disponível.
Inspecionar
Durante o desenvolvimento, você pode usar as DevTools do seu navegador para inspecionar as diferentes tipos de armazenamento e limpar facilmente todos os dados armazenados.
Um novo recurso foi adicionado no Chrome 88 que permite modificar o armazenamento do site no painel de armazenamento. Com esse recurso, você pode simular dispositivos diferentes e testar o comportamento dos aplicativos quando há baixa disponibilidade de disco diferentes. Acesse Aplicativo e depois Armazenamento, ative a opção Simular cota de armazenamento personalizada e digite um número válido para para simular a cota de armazenamento.
Enquanto trabalhava neste artigo, escrevi uma ferramenta simples para tente usar rapidamente o máximo de armazenamento possível. É uma forma rápida e fácil testar diferentes mecanismos de armazenamento e ver o que acontece quando você usar toda a sua cota.
Como lidar com o excesso de cota?
O que você deve fazer quando ultrapassa a cota? Acima de tudo, você deve
sempre detecte e processe erros de gravação, sejam eles QuotaExceededError
ou
outra coisa. Depois, dependendo do design do app, decida como lidar com ele.
Por exemplo, excluir um conteúdo que não foi acessado há muito tempo, remover
com base no tamanho ou fornecer aos usuários uma maneira de escolher o que excluir.
Tanto o IndexedDB quanto a API Cache geram uma DOMError
chamada
QuotaExceededError
quando você exceder a cota disponível.
IndexedDB
Se a origem exceder sua cota, as tentativas de gravação no IndexedDB
falhar. O gerenciador onabort()
da transação será chamado, transmitindo um evento.
O evento vai incluir um DOMException
na propriedade de erro. Verificar o
erro name
retornará QuotaExceededError
.
const transaction = idb.transaction(['entries'], 'readwrite');
transaction.onabort = function(event) {
const error = event.target.error; // DOMException
if (error.name == 'QuotaExceededError') {
// Fallback code goes here
}
};
API Cache
Se a origem excedeu sua cota, tenta gravar na API Cache
será rejeitada com um DOMException
QuotaExceededError
.
try {
const cache = await caches.open('my-cache');
await cache.add(new Request('/sample1.jpg'));
} catch (err) {
if (error.name === 'QuotaExceededError') {
// Fallback code goes here
}
}
Como funciona a remoção?
O armazenamento na Web é categorizado em dois buckets, "Melhor esforço" e "Persistente". Melhor esforço significa que o armazenamento pode ser limpo pelo navegador sem que interrompem o usuário, mas é menos durável para dados críticos ou de longo prazo. O armazenamento permanente não é apagado automaticamente quando há pouco espaço. O usuário precisa limpar esse armazenamento manualmente (pelas configurações do navegador).
Por padrão, os dados de um site (incluindo IndexedDB, Cache API etc.) se enquadram a categoria de melhor esforço, ou seja, a menos que um site tenha solicitou um armazenamento permanente, o navegador poderá remover os dados do site de acordo com os próprios critérios, por exemplo, quando o armazenamento do dispositivo for baixo.
A política de remoção para o melhor esforço é:
- Os navegadores baseados no Chromium vão começar a remover dados quando o navegador acabar de espaço, limpando primeiro todos os dados do site da origem usada menos recentemente depois o próximo, até que o navegador não esteja mais acima do limite.
- O Internet Explorer 10 ou superior não removerá dados, mas impedirá que a origem escrever mais.
- O Firefox começará a remover os dados quando o espaço disponível em disco for preenchido, limpar todos os dados do site da origem usada menos recentemente primeiro e, em seguida, em seguida, até que o navegador não esteja mais acima do limite.
- Anteriormente, o Safari não expulsou os dados, mas recentemente implementou um novo limite de sete dias para todo o armazenamento gravável (veja abaixo).
A partir do iOS e do iPadOS 13.4, e do Safari 13.1 no macOS, há uma limite de sete dias para todo o armazenamento gravável de scripts, incluindo IndexedDB, serviço registro de workers e a API Cache. Isso significa que o Safari vai remover todos conteúdo armazenado em cache após sete dias de uso do Safari, se o usuário não interagem com o site. Esta política de remoção não se aplica a PWAs que foram adicionados à tela inicial. Consulte Bloqueio completo de cookies de terceiros e muito mais no WebKit blog para saber todos os detalhes.
Bônus: por que usar um wrapper para IndexedDB
IndexedDB é uma API de baixo nível que requer configuração significativa antes do uso. o que pode ser particularmente difícil para armazenar dados simples. Ao contrário da maioria das máquinas APIs baseadas em promessas, ela é baseada em eventos. Wrappers de promessas como idb para IndexedDB oculta alguns dos recursos avançados, mas mais O importante é ocultar recursos complexos (por exemplo, transações, controle de versões de esquemas) que acompanha a biblioteca IndexedDB.
Conclusão
Os dias de armazenamento limitado acabaram e os usuários precisam armazenar mais e mais dados. Os sites podem armazenar efetivamente todos os recursos e dados que precisam ser executados. Com a API StorageManager, é possível determinar quanto está disponível para você e quanto você usou. E com armazenamento permanente, a menos que seja removido pelo usuário, você pode protegê-los contra a remoção.
Outros recursos
Obrigado
Um agradecimento especial a Jarryd Goodman, Phil Walton, Eiji Kitamura, Daniel Murphy, Darwin Huang, Josh Bell, Marijn Kruisselbrink e Victor Costan por analisarem neste artigo. Agradecemos a Eiji Kitamura, Addy Osmani e Marc Cohen, que escreveram os artigos originais em que ele se baseia. Eiji escreveu uma ferramenta útil chamado Abuso de armazenamento do navegador, que foi útil para validar comportamento atual. Ele permite que você armazene o máximo de dados possível e veja os limites de armazenamento no seu navegador. Agradecemos a Francois Beaufort, que fez a escavação no Safari para descobrir seus limites de armazenamento.
A imagem principal é de Guillaume Bolduc, em Unsplash: