DEV Community

Cover image for IndexedDB con ExtJS
Luca Minuti
Luca Minuti

Posted on

1

IndexedDB con ExtJS

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.

Cookie

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.

LocalStorage

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']
});
Enter fullscreen mode Exit fullscreen mode

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.

IndexedDB

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'
});
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

Anche in questo caso la variabile value viene valorizzata direttamente con l'oggetto.

Lettura di tutte le chiavi

const keys = await database.store1.keys();
Enter fullscreen mode Exit fullscreen mode

Questo metodo restituisce in array con tutte le chiavi dello store.

Lettura di tutti i valori

const values = await database.store1.values();
Enter fullscreen mode Exit fullscreen mode

Questo metodo restituisce in array con tutti i valori dello store.

Eliminazione di un valore

await database.store1.del(5);
Enter fullscreen mode Exit fullscreen mode

Il metodo del elimina l'elemento indicato dalla chiave.

Eliminazione di tutto lo store

await database.store1.clear();
Enter fullscreen mode Exit fullscreen mode

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!

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay