Sto memorizzando una grande quantità di piccoli oggetti in IndexedDB. Vorrei dare all'utente la possibilità di esportare uno degli archivi oggetti in un file che possono "scaricare".Come posso consentire agli utenti di salvare in modo efficiente il contenuto di un archivio oggetti indicizzato DB in un file?
Ho letto this blog article. Che descrive la lettura dei dati, JSON.stringify
i dati, codificandolo con encodeURIComponent
e ponendolo come href
per un collegamento che possono utilizzare per scaricare i dati. Qualcosa di simile a questo:
var transaction = db.transaction([objectstore], "readonly");
var content = [];
var objectStore = transaction.objectStore(objectstore);
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
content.push({key:cursor.key,value:cursor.value});
cursor.continue();
}
};
transaction.oncomplete = function(event) {
var serializedData = JSON.stringify(dataToStore);
link.attr("href",'data:Application/octet-stream,'+encodeURIComponent(serializedData));
link.trigger("click");
};
Questo è bene, tranne il negozio oggetto avrà milioni di dischi e non mi sento che questo sarà sufficiente performante. C'è un modo per consentire più direttamente all'utente di salvare un archivio oggetti come file (in un modo che posso importare di nuovo tramite la pagina web).
Modifica Da alcune note nei commenti ho riscritto un po 'di come funziona, al fine di ottenere un po' più succo fuori di esso. Il nuovo codice è simile a:
var transaction = db.transaction([objectstore], "readonly");
var objectStore = transaction.objectStore(objectstore);
objectStore.getAll().onsuccess = function(evt) {
var url = window.URL.createObjectURL(new Blob(evt.target.results, {'type': 'application/octet-stream'}));
link.attr('href', url);
link.trigger('click');
};
che darà i risultati come:
- record 10k, 975.87ms tempo medio di esportazione
- 100k record, 5,850.10ms tempo all'esportazione medio
- 1mil record, 56.681.00 ms tempo medio di esportazione
Come si può vedere 1 milione di record richiede circa un minuto per esportare t. C'è un modo migliore per farlo? (Ho anche provato a usare un cursore invece di .getAll()
, ma i cursori sono più lenti)
Voglio dire "utilizzare localStorage per la risorsa attualmente visualizzata (e per il salvataggio/caricamento) e inserire il DB in un WebWorker", ma mi sembra che anche quello non farebbe molto per le prestazioni. –
Sì, ho pensato di eseguire il caricamento e la serializzazione dal webworker, ma deve ancora essere serializzato dal browser per tornare indietro; che penso prenda lo stesso successo in termini di prestazioni. Per quanto riguarda la memorizzazione locale, non penso che mettere 3 milioni di oggetti + sia una buona idea ... – Chad
hai provato? ottenere da 3 milioni di oggetti da IndexedDB dovrebbe richiedere solo pochi secondi. Costruire il file tramite 'window.URL.createObjectURL (il nuovo Blob (contenuto, {'tipo': MIME_TYPE}))' dovrebbe andare bene. –