Spazio di archiviazione per il Web

Esistono molte opzioni diverse per l'archiviazione dei dati nel browser. Qual è il più adatto alle tue esigenze?

Le connessioni a internet possono essere instabili o inesistenti ovunque ti trovi, motivo per cui il supporto offline e l'affidabilità delle prestazioni sono funzionalità comuni app web progressive. Anche con il wireless perfetto ambienti, un uso oculato della memorizzazione nella cache e altre tecniche di archiviazione migliorare notevolmente l'esperienza utente. Esistono diversi modi per memorizzare nella cache le risorse statiche dell'applicazione (HTML, JavaScript, CSS, immagini e così via) dati (dati utente, articoli ecc.). Ma qual è la soluzione migliore? Come e quanti archiviazione si possono memorizzare? Come puoi evitare che venga rimosso?

Che cosa dovrei usare?

Ecco un consiglio generale per l'archiviazione delle risorse:

IndexedDB e l'API Cache Storage sono supportate in tutti i browser moderni. Sono entrambi asincroni e non bloccheranno il thread principale. Sono accessibili dall'oggetto window, dai web worker e dai service worker, rendendo semplificarne l'utilizzo in qualsiasi punto del codice.

E per quanto riguarda gli altri meccanismi di archiviazione?

Nel browser sono disponibili vari altri meccanismi di archiviazione, ma hanno un utilizzo limitato e potrebbero causare problemi di prestazioni significativi.

SessionStorage è specifico per la scheda e ha come ambito per tutta la durata della scheda. Può essere utile per memorizzare piccole quantità di sessioni informazioni specifiche, ad esempio una chiave IndexedDB. Deve essere utilizzato con attenzione perché è sincrona e bloccherà il thread principale. È è limitato a circa 5 MB e può contenere solo stringhe. Poiché sono specifiche per ogni scheda, non è accessibile ai web worker o ai service worker.

LocalStorage deve essere evitato perché è sincrono e bloccherà il thread principale. Ha un limite di circa 5 MB e può contenere solo stringhe. LocalStorage non è accessibile da parte dei web worker o del servizio worker.

I cookie hanno i loro scopi, ma non devono essere usati per l'archiviazione. I cookie vengono inviati con ogni richiesta HTTP, quindi memorizzano qualcosa di più di un una piccola quantità di dati aumenterà significativamente la dimensione di ogni richiesta web. Sono sincroni e non sono accessibili dai web worker. Mi piace LocalStorage e SessionStorage, i cookie sono limitati alle sole stringhe.

L'API File System e l'API FileWriter forniscono metodi per leggere e scrivere file in un file system sandbox. Sebbene sia asincrono, non è consigliato perché disponibile solo nei browser basati su Chromium.

L'API File System Access è stata progettata per per gli utenti può leggere e modificare facilmente i file nel file system locale. L'utente deve concedere l'autorizzazione prima che una pagina possa leggere o scrivere su qualsiasi file locale, e le autorizzazioni non vengono rese persistenti tra le sessioni.

Non utilizzare WebSQL ed è necessario eseguire la migrazione dell'utilizzo esistente a IndexedDB. L'assistenza è stata rimossa da quasi tutti i principali browser. W3C ha smesso di mantenere le specifiche SQL web nel 2010, senza prevedere ulteriori aggiornamenti.

Non utilizzare la cache dell'applicazione e l'utilizzo esistente la migrazione ai service worker e all'API Cache. È stata ritirato e il relativo supporto verrà rimosso dai browser in per il futuro.

Quanto posso memorizzare?

In breve, molti, almeno un paio di centinaia di megabyte e potenzialmente centinaia di gigabyte o più. Le implementazioni dei browser variano, ma la quantità di spazio di archiviazione disponibile si basa in genere sulla quantità di spazio di archiviazione disponibile dispositivo.

  • Chrome consente al browser di utilizzare fino all'80% dello spazio totale su disco. Un'origine può utilizzano fino al 60% dello spazio totale su disco. Puoi usare lo strumento StorageManager API per determinare la quota massima disponibile. Altro a base di cromo browser potrebbero essere diversi.
    • In modalità di navigazione in incognito, Chrome riduce la quantità di spazio di archiviazione utilizzabile da un'origine fino a circa il 5% dello spazio totale su disco.
    • Se l'utente ha attivato l'opzione "Cancella cookie e dati dei siti quando chiudi tutto finestre" in Chrome, la quota di spazio di archiviazione si riduce significativamente per un massimo di circa 300 MB.
    • Vedi il PR n. 3896 per i dettagli sull'implementazione di Chrome.
  • Internet Explorer 10 e versioni successive possono archiviare fino a 250 MB e richiede il dell'utente quando vengono utilizzati più di 10 MB.
  • Firefox consente al browser di utilizzare fino al 50% dello spazio libero su disco. Un eTLD+1 gruppo (ad es. example.com, www.example.com e foo.bar.example.com) può utilizzare fino a 2 GB. Puoi utilizzare lo API StorageManager per determinare la quantità di spazio ancora disponibile disponibili.
  • Safari (sia desktop che mobile) sembra consentire circa 1 GB. Quando viene raggiunto il limite viene raggiunto il numero massimo di utenti, Safari chiederà all'utente di aumentare il limite di 200 MB. di incremento. Non ho trovato alcuna documentazione ufficiale in merito.
    • Se una PWA viene aggiunta alla schermata Home di Safari per dispositivi mobili, sembra che crea un nuovo container di archiviazione e non viene condiviso nulla tra la PWA e Safari per dispositivi mobili. Una volta raggiunta la quota per una PWA installata, non sembra essere un modo per richiedere spazio di archiviazione aggiuntivo.

In passato, se un sito superava una determinata soglia di dati archiviati, la browser chiederà all'utente di autorizzare l'utilizzo di ulteriori dati. Per Ad esempio, se l'origine ha utilizzato più di 50 MB, il browser chiede all'utente di per consentire una memorizzazione fino a 100 MB, quindi effettua nuovamente la richiesta a incrementi di 50 MB.

Oggi, la maggior parte dei browser moderni non consente all'utente di visualizzare la richiesta e consente di fino a raggiungere la quota assegnata. L'eccezione sembra essere Safari, che quando viene superata la quota di spazio di archiviazione, con la richiesta dell'autorizzazione per aumentarla. la quota allocata. Se un'origine tenta di utilizzare più della quota assegnata, ulteriori tentativi di scrivere dati non riuscirà.

Come faccio a verificare la quantità di spazio di archiviazione disponibile?

In molti browser, puoi utilizzare la classe API StorageManager per determinare la quantità di spazio di archiviazione a disposizione dell'origine e la quantità di spazio di archiviazione utilizzata. Riporta il totale di byte utilizzati da IndexedDB e dall'API Cache e rende possibile per calcolare lo spazio di archiviazione residuo approssimativo.

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.`);
}

StorageManager non è ancora implemented in tutti i browser, quindi deve rilevarlo prima di utilizzarlo. Anche quando è disponibile, devi rilevare eventuali errori di superamento della quota (vedi sotto). In alcuni casi, è possibile che la quota disponibile per superare la quantità effettiva di spazio di archiviazione disponibile.

Ispeziona

Durante lo sviluppo, puoi usare DevTools del browser per esaminare diversi tipi di archiviazione e cancellare facilmente tutti i dati memorizzati.

In Chrome 88 è stata aggiunta una nuova funzionalità che ti consente di eseguire l'override dello spazio di archiviazione del sito nel riquadro Archiviazione. Questa funzione consente di simulare dispositivi diversi e testa il comportamento delle tue app in caso di scarsa disponibilità del disco diversi scenari. Vai ad Applicazione, poi Spazio di archiviazione, attiva Simula quota di spazio di archiviazione personalizzata e inserisci un numero valido per simulare la quota di spazio di archiviazione.

riquadro Archiviazione DevTools.

Mentre lavoravo a questo articolo, ho scritto uno strumento semplice per e provare a utilizzare rapidamente tutto lo spazio di archiviazione possibile. È un modo semplice e veloce di sperimentare diversi meccanismi di archiviazione e vedere cosa succede utilizzi tutta la tua quota.

Come gestire il superamento della quota?

Cosa devi fare se superi la quota? Cosa più importante, dovresti rileva e gestisce sempre gli errori di scrittura, che si tratti di un QuotaExceededError o altro. Quindi, a seconda del design della tua app, decidi come gestirla. Ad esempio, elimina i contenuti che non vengono visualizzati da molto tempo, rimuovili, dati in base alle dimensioni o permettere agli utenti di scegliere cosa eliminare.

Sia IndexedDB che l'API Cache restituiscono un DOMError denominato QuotaExceededError quando superi la quota disponibile.

IndexedDB

Se l'origine ha superato la quota, i tentativi di scrittura su IndexedDB non riuscito. Verrà chiamato il gestore onabort() della transazione, che trasmetterà un evento. L'evento includerà un DOMException nella proprietà di errore. Controllo del l'errore name restituirà 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 l'origine ha superato la quota, tenta di scrivere nell'API Cache rifiuterà con un QuotaExceededError DOMException.

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
  }
}

Come funziona l'espulsione?

Lo spazio di archiviazione web è classificato in due bucket, "Miglior sforzo" e "Persistente". Il massimo impegno significa che lo spazio di archiviazione può essere cancellato dal browser senza interrompendo l'utente, ma hanno meno durabilità per dati critici o a lungo termine. Lo spazio di archiviazione permanente non viene cancellato automaticamente quando lo spazio di archiviazione è in esaurimento. L'utente deve cancellare manualmente questo spazio di archiviazione (tramite le impostazioni del browser).

Per impostazione predefinita, i dati di un sito (inclusi IndexedDB, API Cache e così via) rientrano in la categoria best effort, ovvero a meno che un sito non abbia di archiviazione permanente richiesto, il browser potrebbe rimuovere dati del sito a sua discrezione, ad esempio quando lo spazio di archiviazione del dispositivo è in esaurimento.

Le norme di eliminazione per il massimo impegno sono:

  • I browser basati su Chromium inizieranno a rimuovere i dati quando il browser si esaurisce di spazio, cancellando prima tutti i dati dei siti dall'origine utilizzata meno di recente. poi quello successivo, fino a quando il browser non supera più il limite.
  • Internet Explorer 10 e versioni successive non rimuoverà i dati, ma impedirà all'origine a scrivere ancora.
  • Firefox inizia a rimuovere i dati quando lo spazio su disco disponibile è esaurito, cancellare prima tutti i dati dei siti dall'origine utilizzata meno di recente, poi fino a quando il browser non supererà più il limite.
  • Safari non ha rimosso i dati, ma di recente ha implementato una nuova un limite di sette giorni per l'archiviazione scrivibile (vedi di seguito).

A partire da iOS e iPadOS 13.4 e Safari 13.1 su macOS, è disponibile un limite di sette giorni per l'archiviazione scrivibile degli script, compreso IndexedDB, servizio registrazione dei worker e l'API Cache. Ciò significa che Safari rimuoverà tutti contenuti dalla cache dopo sette giorni di utilizzo di Safari se l'utente non interagire con il sito. Questo criterio di eliminazione non si applica ai domini installati PWA che sono state aggiunte alla schermata Home. Consulta Blocco completo dei cookie di terze parti e altro ancora sul WebKit blog per tutti i dettagli.

Bonus: perché utilizzare un wrapper per IndexedDB

IndexedDB è un'API di basso livello che richiede una configurazione significativa prima dell'uso, il che può essere particolarmente complicato per archiviare dati semplici. A differenza della maggior parte delle API basate su promessa, è basata sugli eventi. Wrapper promettenti come idb per IndexedDB nasconde alcune delle potenti funzionalità ma più soprattutto, nascondi i macchinari complessi (ad es. transazioni, controllo delle versioni dello schema) fornita con la libreria IndexedDB.

Conclusione

Sono finiti i giorni in cui era limitato lo spazio di archiviazione e in cui veniva chiesto all'utente di archiviare più spazio più dati. I siti possono archiviare in modo efficace tutte le risorse e i dati per l'esecuzione. Con l'API StorageManager puoi determinare quanto hai a disposizione e quanto hai utilizzato. E con spazio di archiviazione permanente, a meno che l'utente non lo rimuova, può proteggerlo dall'espulsione.

Risorse aggiuntive

Grazie

Un ringraziamento speciale a Jarryd Goodman, Phil Walton, Eiji Kitamura, Daniel Murphy, Darwin Huang, Josh Bell, Marijn Kruisselbrink e Victor Costan per le recensioni questo articolo. Grazie a Eiji Kitamura, Addy Osmani e Marc Cohen, che hanno scritto gli articoli originali su cui si basa. Eiji ha scritto uno strumento utile chiamato Browser Storage Abuser, utile per convalidare comportamento attuale. Consente di archiviare quanti più dati possibile e di vedere limiti di spazio di archiviazione sul tuo browser. Grazie a Francois Beaufort, che si è occupato della in Safari per determinarne i limiti.

L'immagine hero è di Guillaume Bolduc su Annulla schermata.