Memorizzazione di dati immagine per applicazione Web offline (database di archiviazione lato client)

Ho un’applicazione web offline usando l’appcaching. Devo fornire circa 10 MB – 20 MB di dati che verranno salvati (lato client) costituiti principalmente da file immagine PNG. L’operazione è la seguente:

  1. Download e installazioni di applicazioni Web in appcache (utilizza manifest)
  2. Richieste di app Web dai file di dati PNG del server (come? – vedere le alternative di seguito)
  3. Occasionalmente, l’app web risincronizza con il server e esegue piccoli aggiornamenti / eliminazioni / aggiunte al database PNG
  4. Nota: il server è un server JSON REST, che può posizionare file in wwwroot per il ritiro

Ecco la mia attuale analisi dei “database” basati su client che gestiscono lo storage blob binario

VEDI AGGIORNAMENTO in basso

  • AppCache (via manifest aggiungi tutto il PNG e poi aggiorna a richiesta)
    • CON: qualsiasi modifica di un elemento del database PNG comporterà il download completo di tutti gli elementi in manifest (notizie davvero cattive!)
  • WebStorage
    • CON: progettato per l’archiviazione JSON
    • CON: può solo memorizzare BLOB tramite la codifica base64 (probabilmente fatale difetto dovuto al costo della decodifica)
    • CON: Hard limit di 5 MB per webStorage http://htmlui.com/blog/2011-08-23-5-obscure-facts-about-html5-localstorage.html
  • PhoneGap e SQLLite
    • CON: lo sponsor la rifiuterà come app nativa che richiede la certificazione
  • file zip
    • Il server crea un file zip, lo inserisce in wwwroot e lo notifica al client
    • l’utente deve decomprimere manualmente (almeno questo è come lo vedo io) e salvare nel file system del client
    • L’app Web utilizza l’API FileSystem per fare riferimento ai file
    • CON: ZIP potrebbe essere troppo grande (zip64?), Molto tempo per creare
    • CON: Non sono sicuro che l’API FileSystem possa sempre leggere fuori dalla sandbox (penso di sì)
  • USB o scheda SD (torna all’età della pietra ….)
    • L’utente sarà locale al server prima di andare offline
    • Quindi potremmo fargli inserire una scheda SD, lasciare che il server lo riempia di file PNG
    • Quindi l’utente lo collegherà al laptop, al tablet
    • L’app Web utilizzerà l’API FileSystem per leggere i file
    • CON: Non sono sicuro che l’API FileSystem possa sempre leggere fuori dalla sandbox (penso di sì)
  • WebSQL
    • CON: w3c lo ha abbandonato (piuttosto male)
    • Potrei considerare un wrapper Javascript che utilizza IndexedDB e WebSQL come fallback
  • API FileSystem
    • Chrome supporta la lettura / scrittura di BLOB
    • CON: non chiaro su IE e FireFox (IE10, ha msSave non standard)
    • caniuse.com riporta IOS e supporto per Android (ma ancora, questo è solo un r / n di JSON, o include l’API blob completa per la scrittura?
    • CON: a chi non ama l’API FileSystem di FireFox non è chiaro se supporta il salvataggio dei BLOB: https://hacks.mozilla.org/2012/07/why-no-filesystem-api-in-firefox/
    • PRO: molto più veloce di IndexedDB per blob secondo jsperf http://jsperf.com/indexeddb-vs-localstorage/15 (pagina 2)
  • IndexedDB
    • Buon supporto in IE10, FireFox (salva, leggi BLOB)
    • Buona velocità e gestione più semplice di un file system (cancella, aggiorna)
    • PRO: vedere i test di velocità: http://jsperf.com/indexeddb-vs-localstorage/15
    • Vedi questo articolo su come archiviare e visualizzare le immagini in IndexedDB: https://hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/
    • CON: Ho confermato che Chrome non supporta ancora la scrittura blob (bug corrente, ma non chiaro quando verrà risolto)
    • AGGIORNAMENTO: gli sviluppatori di Chrome confermano che stanno lavorando su questo sia per desktop che per android! nessuna cronologia ancora.
  • Wrapper JavaScript LawnChair http://brian.io/lawnchair/
    • PRO: wrapper molto pulito per IndexedDB, WebSQL o qualsiasi altro database (think polyfill)
    • CON: imansible memorizzare blob binari, solo dati: uri (codifica base64) (probabilmente fatale difetto dovuto al costo della decodifica)
  • IndexedDB JQUERY polyFill https://github.com/axemclion/jquery-indexeddb
    • Parashuram ha distrutto un bel wrapper JQUERY per l’interfaccia raw IndexedDB
    • PRO: semplifica notevolmente l’uso di IndexedDB, speravo di aggiungere uno shim / polyfill per Chrome FileSystemAPI
    • CON: Dovrebbe gestire i BLOB, ma non sono riuscito a farlo funzionare
  • idb.filesystem.js http://ericbidelman.tumblr.com/post/21649963613/idb-filesystem-js-bringing-the-html5-filesystem-api
    • Eric Bidelman @ Google ha scritto una collaudata PolyFill l’API FileSystem che utilizza il DB indicizzato come ripiego
    • PRO: l’API FileSystem è adatta per la memorizzazione di BLOB
    • PRO: funziona alla grande su FireFox e Chrome
      • PRO: ottimo per la sincronizzazione con CouchDB basato su cloud
    • CON: non chiaro perché, ma non funziona su IE10
  • Libreria JavaScript PouchDB http://pouchdb.com/
    • ottimo per sincronizzare un CouchDB con un DB locale (utilizza WebSQL o IndexedDB (non il mio problema)
    • CON: NO CONS, PouchDB ora supporta blob binari per tutti i browser recenti (IE, Chrome, Firefox, Chrome su dispositivi mobili, ecc.) E molti browser più vecchi. Non è stato il caso quando ho fatto questo post per la prima volta.

NOTA: per vedere un dato: codifica uri di PNG ho creato un esempio su: http://jsbin.com/ivefak/1/edit

Funzioni desiderate / utili / non necessarie

  • Nessuna app nativa (EXE, PhoneGap, ObjectiveC, ecc.) Sul client (applicazione Web pura)
  • Deve solo essere eseguito sugli ultimi Chrome, FireFox, IE10 per laptop
  • Vogliamo fortemente la stessa soluzione per il tablet Android (anche IOS sarebbe bello) ma per funzionare ha bisogno solo di un browser (FF, Chrome, ecc.)
  • Popolazione DB iniziale veloce
  • REQUISITO: Recupero molto rapido di immagini per applicazione Web dalla memoria (DB, file)
  • Non destinato ai consumatori. Possiamo limitare i browser e chiedere all’utente di eseguire impostazioni e attività speciali, ma riduciamo al minimo questo

Implementazioni IndexedDB

  • C’è un eccellente articolo su come IE, FF e Chrome implementano internamente questo in: http://www.aaron-powell.com/web/indexeddb-storage
  • In breve:
    • IE utilizza lo stesso formato di database di Exchange e Active Directory per IndexedDB
    • Firefox utilizza SQLite, quindi è come implementare un database NoSQL nel database SQL
    • Chrome (e WebKit) utilizzano un archivio Key / Value che ha un patrimonio in BigTable

I miei risultati attuali

  • Ho scelto di utilizzare un approccio IndexedDB (e polyfill con FileSystemAPI per Chrome fino a quando non inviano il supporto blob)
  • Per il recupero delle tessere, ho avuto un dilemma dal momento che gli utenti di JQUERY stanno cercando di aggiungere questo ad AJAX
  • Sono andato con XHR2-Lib di Phil Parsons, che è molto simile a JQUERY .ajax () https://github.com/pmp/xhr2-lib
  • Prestazioni per download da 100 MB (IE10 4s, Chrome 6s, FireFox 7s).
  • Non sono riuscito a far funzionare nessuno dei wrapper IndexedDB per i BLOB (sedia a sdraio, PouchDB, jquery-indexeddb, ecc.)
  • Ho fatto il mio wrapper e le prestazioni sono (IE10 2s, Chrome 3s, FireFox 10s)
  • Con FF, presumo che stiamo assistendo al problema di prestazioni dell’utilizzo di un DB relazionale (sqllite) per uno spazio non sql
  • NOTA, Chrome ha strumenti di debug in sospeso (scheda sviluppatore, risorse) per l’ispezione dello stato di IndexedDB.

Risultati FINALI pubblicati di seguito come risposta

Aggiornare

PouchDB ora supporta blob binari per tutti i browser recenti (IE, Chrome, Firefox, Chrome su dispositivi mobili, ecc.) E molti browser meno recenti. Non è stato il caso quando ho fatto questo post per la prima volta.

Risultati cache di BLOB offline per mappe slippy PNG

analisi

  • 171 file PNG (totale di 3,2 MB)
  • Piattaforms testate: Chrome v24, FireFox 18, IE 10
  • Dovrebbe funzionare anche con Chrome e FF per Android

Recupera dal server web

  • utilizzando XHR2 (supportato su quasi tutti i browser) per il download di BLOB dal server web
  • Sono andato con XHR2-Lib di Phil Parsons, che è molto simile a JQUERY .ajax ()

Conservazione

Display

  • Sto usando Leaflet http://leafletjs.com/ per mostrare le tessere della mappa
  • Ho usato il plug-in funzionale del tile layer di Ishmael Smyrnow per il recupero del layer di tile dal DB
  • Ho confrontato il layer Tile basato su DB con uno storage puramente locale (localhost: //)
  • Non ci sono differenze evidenti nelle prestazioni! tra l’utilizzo di IndexedDB e file locali!

risultati

  • Chrome: recupero (6.551s), archivio (8.247s), tempo totale trascorso: (13.714s)
  • FireFox: Fetch (0.422s), Store (31.519s), Tempo trascorso totale: (32.836s)
  • IE 10: recupero (0,668 s), archivio: (0,896 s), tempo totale trascorso: (3,7758 s)

Per le tue esigenze suggerisco che lo sviluppo di un nuovo polyfill basato su altri due: l’ API FileSystem su IndexedDB e IndexedDB su WebSQL – sia l’opzione migliore.

Il primo consentirà il supporto per la memorizzazione di BLOB in Chrome (API FileSystem) e Firefox (IndexedDB), mentre il secondo dovrebbe fornire il supporto per Android e iOS ( WebSQL ). Ciò che è necessario è solo far funzionare questi poliforni e suppongo che non sia difficile.

NB: Dal momento che non sono riuscito a trovare alcuna informazione sul web su questo, si dovrebbe verificare se la memorizzazione dei BLOB usando il polyfill WebSQL funzionerà su iOS e Android. Sembra che dovrebbe funzionare però:

var sql = ["CREATE TABLE", idbModules.util.quote(storeName), "(key BLOB", createOptions.autoIncrement ? ", inc INTEGER PRIMARY KEY AUTOINCREMENT" : "PRIMARY KEY", ", value BLOB)"].join(" ") 

fonte

Qualche anno fa (non esattamente l’età della pietra), stavo usando un’applet java firmata che interrogava il suo server per i requisiti di sincronizzazione / aggiornamento, scaricava i file appropriati dal server e li salvava sul filesystem dell’utente (non su un database). Questa soluzione potrebbe funzionare per te, anche se avrai bisogno di qualcuno per scrivere l’applet e firmarlo. Per le soluzioni di database, tale applet può utilizzare jdbc disponibile per la maggior parte dei database utilizzando localhost su una porta idonea (ad esempio, 3306 per MySQL). Credo che il tag applet sia deprecato in Html5 ma funziona ancora. Nessuna esperienza su tablet Android, quindi non posso commentare su quella parte.

Ho esempi di memorizzazione nella cache delle mappe (esempio aperto, individuazione di regioni e zoom, commutazione offline e aree scoperte saranno disponibili).

Ci sono map.js – layer mappa per tiles offline, storage.js – implementazione storage basata su IndexedDb e WebSQL (ma questa è solo un’implementazione di test con prestazioni scadenti).

  • Per i file del sito (html, css, js e così via) preferisco usare la cache dell’applicazione.
  • Per l’archiviazione preferisco usare DB indicizzati (blob di supporto), Web SQL (solo base64), FileWriter (blob di supporto, ma solo chrome). Francamente lo stoccaggio è un grosso problema per questo. È necessaria la soluzione di valore chiave più rapida che le mescoli tutte. Penso che sia una buona decisione usare la soluzione esistente.
  • Per il recupero ho usato la canvas con CORS. Ma penso a WebWorkers e XHR2 e questo può essere migliore, invece, perché canvas ha qualche problema con CORS in diversi browser e altro (ad esempio questo titolo è stato memorizzato male nell’opera ).

Ulteriori informazioni sulle dimensioni per 2 miliardi di città ( Minsk ):

  • Zoom – 9, tile – 2, size – 52 kb, con precedente – 52 kb;
  • Zoom – 10, tiles – 3, size – 72 kb, con precedente – 124 kb;
  • Zoom – 11, tiles – 7, size – 204 kb, con precedente – 328 kb;
  • Zoom – 12, tiles – 17, size – 348 kb, con precedente – 676 ​​kb;
  • Zoom – 13, tessere – 48, dimensioni – 820 kb, con precedente – 1,5 mb;
  • Zoom – 14, tessere – 158, dimensioni – 2,2 mb, con precedente – 3,7 mb;
  • Zoom – 15, tessere – 586, dimensioni – 5,5 mb, con precedente – 9,3 mb;
  • Zoom – 16, tessere – 2264, dimensioni – 15 mb, con precedente – 24,3 mb;