La possibilità di salvare informazioni localmente sul browser è una funzionalita molto utile che si è evoluta nel tempo. Ovviamente sul browser, per motivi di sicurezza, non è possibile scrivere e leggere a piacimento sul file system dell'utente. Ma tramite diversi meccanismi è comunque possibile memorizzare delle informazioni in maniera persistente.
In questo articolo vedremo diversi tipi di storage e come utilizzarli con ExtJS. In particolare analizzeremo l'implementazione di IndexedDB offerta dalla libreria (N)ext.
Cookie
Il modo "classico" di salvare dati sul browser è tramite i cookie che permettono proprio di salvare piccole stringhe da recuperare in un secondo tempo dal server oppure direttamente sul browser tramite codice JavaScript. Più recentemente sono strati introdotti dei veri e propri database: LocalStorage, SessionStorage e IndexexDB.
LocalStorage e SessioneStorage
localStorage e SessionStorage sono due semplici database chiave/valore presenti nel browser. In pratica per ogni "origin" (host+porta) è possibile associare una serie chiavi a dei valori in modo da poterli recuperare in un secondo tempo.
La differenza tra i due è che mentre il LocalStorage è permanente, i dati contenuti nel SessionStorage vengono eliminati alla chiusura del browser.
Limitazioni
I problemi principali di questi tipi di storage sono i seguenti:
- Le dimensioni: ci sono differenze tra i vari browser ma in generale non è possibile salvare più di 5MB di dati
- L'API è sincrona, quindi se la dimensione dei dati è consistente o si eseguono molte operazioni di lettura/scrittura si rischia di "freezare" il browser.
- Gli elementi vengono salvati come stringa (eventualmente chiamando il metodo
toString()
), di conseguenza per gli oggetti più complessi è necessario eseguire una conversione manualmente.
ExtJS
In ExtJS ci sono varie classi che fanno uso di questi tipi di storage:
- Ext.util.LocalStorage: Questa classe è un semplice wrapper della classe localStorage nativa del browser. Semplicemente si limita a salvare i dati localmente nel caso in cui il browser non supporti localStorage.
- Ext.state.LocalStorage: Questa classe serve a salvare lo stato dei componenti (dimensione, posizione, ecc.) in modo da ripresentarli ad una successiva apertura dell'applicazione (vedi Ext.Stateful).
- Ext.data.proxy.LocalStorage: Questo proxy, collegato ad uno store, permette di leggere e scrivere dati dal localStorage.
- Ext.data.proxy.SessionStorage: Esattamente come il precedente ma legge e scrive sul SessionStorage.
IndexedDB
Per ovviare ai problemi di LocalStorage da qualche tempo su tutti i principali browser desktop e mobili (vedi browser supportati) è possibile usare IndexedDB. A differenza di LocalStorage consente alle applicazioni web di memorizzare grandi quantità di dati strutturati, offrendo un'interfaccia di accesso flessibile e basata sulle Promise.
funzionalità principali
- Modello di dati: IndexedDB supporta la memorizzazione di oggetti JavaScript complessi, consentendo la memorizzazione di dati strutturati in modo gerarchico.
- Dimensione dei dati: IndexedDB gestisce grandi quantità di dati in modo più efficiente rispetto a localStorage.
- Interfaccia di accesso: IndexedDB fornisce un'interfaccia di programmazione più complessa rispetto a localStorage. Richiede la comprensione di concetti come transazioni, cursori e indici per manipolare i dati in modo efficiente.
- Supporto per transazioni: IndexedDB supporta le transazioni, consentendo operazioni atomiche su più record di dati.
- Performance: IndexedDB è progettato per gestire grandi quantità di dati in modo efficiente, offrendo prestazioni migliori rispetto a localStorage.
Il difetto principale di IndexedDB è proprio la complessità dell'API. In JavaScript esistono diverse librerie che cercano di semplificarne l'uso, per esempio:
In particolare IDB-Keyval offre un'API estremamente semplificata che ricorda molto quella di LocalStorage. Questa semplificazione chiaramente ha delle conseguenze e infatti alcune caratteristiche avanzate di IndexedDB (come l'uso delle transazioni) vengono meno. Ma per chi viene da LocalStorage e ha bisogno semplicemente di più performance e spazio di archiviazione sicuramente è una scelta interessante.
ExtJS - (N)ext
Purtroppo in ExtJS non c'è nessun supporto nativo per IndexedDB. Ed è per questo che ho deciso di aggiungerlo nella libreria (N)ext che ho recentemente pubblicato su GitHub.
Con (N)ext è possibile connettersi ad un database in questo modo:
// If you add a new store in the schema you must increment the database version!
database = await Next.IndexedDB.open('dbname', {
version: 1,
stores: ['store1','store2', 'store3', 'store4']
});
Se il database non esiste verrà creato con i 4 store (che non hanno niente a che fare con gli store di ExtJS), che si possono considerare come delle tabelle. Per come funziona IndexedDB è importante ricordarsi che qualora serva uno store addizionale è necessario incrementare il numero di versione.
È importante notare che l'apertura del database (come praticamente tutte le altre API) è asincrona. Infatti nell'esempio viene chiamata usando await
.
Una volta ottenuto un riferimento al database è possibile interagire con gli store. La libreria offre diverse possibilità, di seguito sono elencate le principali.
Inserimento/modifica di un elemento sullo store
await database.store1.set(5, {
name: 'Charlie'
});
Come si può vedere dall'esempio il valore è un oggetto e, in questo caso, non c'è bisogno di nessuna trasformazione.
Lettura di un valore
const value = await database.store1.get(5);
Anche in questo caso la variabile value
viene valorizzata direttamente con l'oggetto.
Lettura di tutte le chiavi
const keys = await database.store1.keys();
Questo metodo restituisce in array con tutte le chiavi dello store.
Lettura di tutti i valori
const values = await database.store1.values();
Questo metodo restituisce in array con tutti i valori dello store.
Eliminazione di un valore
await database.store1.del(5);
Il metodo del
elimina l'elemento indicato dalla chiave.
Eliminazione di tutto lo store
await database.store1.clear();
Questo metodo svuota l'intero store.
Conclusioni
In questo articolo abbiamo visto i principali metodi per salvare informazioni persistenti sul browser in particolare con IndexedDB. Ci siamo poi soffermati ad analizzare quanto offerto dalla libreria GitHub.
Vi invito a provarla e farmi sapere le vostre impressioni!
Top comments (0)