Archiviazione dei dati dell'immagine per l'applicazione Web offline (database di archiviazione lato client)


105

Ho un'applicazione web offline che utilizza appcaching. Devo fornire circa 10 MB - 20 MB di dati che salverà (lato client) costituiti principalmente da file di immagine PNG. L'operazione è la seguente:

  1. Download e installazione di applicazioni Web in appcache (utilizza manifest)
  2. Richieste di app Web da file di dati PNG del server (come? - vedere le alternative di seguito)
  3. Di tanto in tanto l'app web si risincronizza con il server ed esegue piccoli aggiornamenti / eliminazioni / aggiunte parziali al database PNG
  4. FYI: il server è un server REST JSON, che può posizionare i file in wwwroot per il ritiro

Di seguito è riportata la mia attuale analisi dei "database" basati su client che gestiscono l'archiviazione BLOB binario

VEDI AGGIORNAMENTO in basso

  • AppCache (tramite manifest aggiungi tutto il PNG e poi aggiorna su richiesta)
    • CONTRO: qualsiasi modifica di un elemento del database PNG significherà il download completo di tutti gli elementi nel manifest (davvero una brutta notizia!)
  • WebStorage
  • PhoneGap e SQLLite
    • CONTRO: lo sponsor la rifiuterà come app nativa che richiede la certificazione
  • file zip
    • Il server crea un file zip, lo inserisce in wwwroot e invia una notifica al client
    • l'utente deve decomprimere manualmente (almeno è così che lo vedo) e salvare nel file system del client
    • L'app Web utilizza l'API FileSystem per fare riferimento ai file
    • CONTRO: ZIP potrebbe essere troppo grande (zip64?), Molto tempo per la creazione
    • CONTRO: Non sono sicuro che l'API FileSystem possa sempre leggere fuori dalla sandbox (penso di sì)
  • USB o scheda SD (indietro all'età della pietra ....)
    • L'utente sarà locale sul server prima di andare offline
    • Quindi potremmo fargli inserire una scheda SD, lasciare che il server la riempia con file PNG
    • Quindi l'utente lo collegherà al laptop, tablet
    • L'app Web utilizzerà l'API FileSystem per leggere i file
    • CONTRO: Non sono sicuro che l'API FileSystem possa sempre leggere fuori dalla sandbox (penso di sì)
  • WebSQL
    • CONTRO: w3c l'ha abbandonato (piuttosto male)
    • Potrei considerare un wrapper Javascript che utilizza IndexedDB e WebSQL come riserva
  • FileSystem API
  • IndexedDB
    • Buon supporto in IE10, FireFox (salva, leggi i blob)
    • Buona velocità e gestione più semplice rispetto a un file system (eliminazioni, aggiornamenti)
    • PRO: vedi test di velocità: http://jsperf.com/indexeddb-vs-localstorage/15
    • Vedi questo articolo sull'archiviazione e la visualizzazione di immagini in IndexedDB: https://hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/
    • CONTRO: Ho confermato che Chrome non supporta ancora la scrittura di 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 sequenza temporale ancora.
  • Wrapper JavaScript LawnChair http://brian.io/lawnchair/
    • PRO: wrapper molto pulito per IndexedDB, WebSQL o qualsiasi database tu abbia (pensa a polyfill)
    • CONTRO: impossibile memorizzare BLOB binari, solo dati: uri (codifica base64) (difetto probabilmente fatale a causa del costo della decodifica)
  • IndexedDB JQUERY polyFill https://github.com/axemclion/jquery-indexeddb
    • Parashuram ha scritto un bel wrapper JQUERY per l'interfaccia IndexedDB non elaborata
    • PRO: semplifica notevolmente l'utilizzo di IndexedDB, speravo di aggiungere uno shim / polyfill per Chrome FileSystemAPI
    • CONTRO: 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 un PolyFill ben collaudato API FileSystem che utilizza DB indicizzato come ripiego
    • PRO: FileSystem API è adatta per archiviare i BLOB
    • PRO: funziona alla grande su FireFox e Chrome
      • PRO: ottimo per la sincronizzazione con CouchDB basato su cloud
    • CONTRO: 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 è un mio problema però)
    • CONTRO: NESSUN CONTRO, PouchDB ora supporta i BLOB binari per tutti i browser recenti (IE, Chrome, Firefox, Chrome su dispositivi mobili, ecc.) Così come molti browser meno recenti. Non è stato così quando ho scritto per la prima volta questo post.

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

Caratteristiche desiderate / utili / non necessarie

  • Nessuna app nativa (EXE, PhoneGap, ObjectiveC, ecc.) Sul client (applicazione web pura)
  • Deve essere eseguito solo sull'ultimo Chrome, FireFox, IE10 per laptop
  • Desidero fortemente la stessa soluzione per tablet Android (anche IOS sarebbe bello) ma per funzionare è necessario un solo browser (FF, Chrome, ecc.)
  • Popolazione DB iniziale rapida
  • REQUISITO: Recupero molto veloce delle immagini dall'applicazione web dalla memoria (DB, file)
  • Non pensato per i consumatori. Possiamo limitare i browser e chiedere all'utente di eseguire impostazioni e attività speciali, ma riduciamolo al minimo

Implementazioni IndexedDB

  • C'è un eccellente articolo su come IE, FF e Chrome implementano internamente questo a: 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 implementa un database NoSQL nel database SQL
    • Chrome (e WebKit) utilizzano un archivio chiave / valore che ha eredità in BigTable

I miei risultati attuali

  • Ho scelto di utilizzare un approccio IndexedDB (e polyfill con FileSystemAPI per Chrome fino a quando non viene fornito il supporto blob)
  • Per il recupero delle tessere, ho avuto un dilemma dal momento che le persone 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 (sdraio, PouchDB, jquery-indexeddb, ecc.)
  • Ho arrotolato il mio wrapper e le prestazioni sono (IE10 2s, Chrome 3s, FireFox 10s)
  • Con FF, presumo che stiamo riscontrando il problema delle prestazioni dell'utilizzo di un DB relazionale (sqllite) per uno storage non sql
  • NOTA, Chrome dispone di eccezionali strumenti di debug (scheda sviluppatore, risorse) per l'ispezione dello stato di IndexedDB.

Risultati FINALI pubblicati di seguito come risposta

Aggiornare

PouchDB ora supporta i BLOB binari per tutti i browser recenti (IE, Chrome, Firefox, Chrome su dispositivi mobili, ecc.) Oltre a molti browser meno recenti. Non è stato così quando ho scritto per la prima volta questo post.


1
webstorage non supporta json ma stringhe, quindi puoi codificare in base64 le tue imagez e restituirle come dataurl.
mpm

Ok, ma probabilmente non ottimale (o entro la quota) per 20 MB di immagini, che in realtà sono tessere di mappa scivolose, che devono essere recuperate e visualizzate rapidamente da un'applicazione di mappe LEAFLET mentre esegui lo zoom e la panoramica.
Dr.YSG

La ricerca che hai fatto è molto utile.
Bogdan Kulynych

il punto è che non è necessario gestire i blob binari se si utilizzano immagini png.
mpm

Hai ragione, ti dispiacerebbe se aggiorno il documento per riflettere il tuo input?
Dr.YSG

Risposte:


25

Risultati Cache BLOB offline per mappe slippy PNG

analisi

  • 171 file PNG (totale di 3,2 MB)
  • Piattaforme 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

Schermo

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

risultati

  • Chrome: recupero (6.551 s), Store (8.247 s), tempo trascorso totale: (13.714 s)
  • FireFox: Recupera (0.422s), Store (31.519s), Tempo trascorso totale: (32.836s)
  • IE 10: Fetch (0.668s), Store: (0.896s), Tempo trascorso totale: (3.758s)

4

Per le tue esigenze suggerisco che lo sviluppo di un nuovo polyfill basato su altri due: FileSystem API to IndexedDB e IndexedDB to WebSQL - è l'opzione migliore.

Il primo abiliterà il supporto per l'archiviazione di BLOB in Chrome (FileSystem API) e Firefox (IndexedDB), mentre il secondo dovrebbe fornire il supporto per Android e iOS ( WebSQL ). Quello che serve è solo far lavorare questi polyfill insieme, e suppongo non sia difficile.

NB: Dal momento che non sono riuscito a trovare alcuna informazione sul Web in merito, dovresti verificare se l'archiviazione di BLOB utilizzando il polyfill WebSQL funziona 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


Mi avvicino al tuo suggerimento, ma aspetto di sentire gli altri. Non ho Android a portata di mano, ma sarebbe bene creare un jsBin o jsFiddle e vedere cosa funziona su Android.
Dr.YSG

1
Questi due blob sono diversi. Il blob sqlite è arraybuffer in javascript, mentre il blob js non ha equivalenti in sqlite. Blob non può essere convertito in arraybuffer, sebbene possa essere clonato strutturalmente.
Kyaw Tun

2

Ho esempi di memorizzazione nella cache delle mappe (esempio aperto, scopri regioni e zoom, passa offline e le regioni scoperte saranno disponibili).

Ci sono map.js- map layer per tile offline, storage.js- implementazione dello storage basata su IndexedDb e WebSQL (ma questo prova solo l'implementazione con scarse prestazioni).

  • Per i file del sito (html, css, js e così via) preferisco usare la cache dell'applicazione.
  • Per l'archiviazione preferisco usare Indexed DB (supporto blob), Web SQL (solo base64), FileWriter (supporto blob, ma solo chrome). Francamente l'archiviazione è un grosso problema per questo. Hai bisogno della soluzione di valore chiave più veloce che li mescoli tutti. Penso che sia una buona decisione usare la soluzione esistente.
  • Per il recupero ho usato canvas con CORS. Ma penso a WebWorkers e XHR2 e questo può essere meglio invece canvas perché canvas ha alcuni problemi con CORS in browser diversi e altri (ad esempio questo titolo è stato memorizzato male in opera ).

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

  • Zoom - 9, piastrelle - 2, dimensione - 52 kb, con precedente - 52 kb;
  • Zoom - 10, piastrelle - 3, dimensione - 72 kb, con precedente - 124 kb;
  • Zoom - 11, tessere - 7, dimensioni - 204 kb, con precedente - 328 kb;
  • Zoom - 12, tessere - 17, dimensioni - 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;

Presumo che quelle siano tessere JPG nel formato slippy EGPS3857, giusto? poiché sto usando il volantino e sto facendo raster ovelays, ho dovuto usare PNG. controlla anche la mia demo sull'utilizzo di PouchDB (che utilizza IDB sotto). stackoverflow.com/questions/16721312/...
Dr.YSG

Oh sì, stai memorizzando nella cache al volo, ma sai dove posso andare per ottenere una mappa OSM pre-costruita (in tutto il mondo) per ingrandire 10 o 11 o 12? Lo terremo sul nostro server offline.
Dr.YSG

No, utilizzato PNGcon la proiezione predefinita (EGPS: 3857) ma non importa JPEGo PNGperché utilizzato da imgtag o canvas. Con il mio esempio puoi semplicemente precaricare le tessere se conosci le chiavi delle tessere ( storage.add('x_y_z', 'data:image/png;base64,...')per ciascuna tessera memorizzata), ma puoi sempre ottenerle se conosci solo i limiti (poligono) e gli zoom.
tbicr

Voglio assicurarmi che non abbiamo problemi di lingua. C'è qualche posto in cui possiamo ottenere un set OSM di tessere scivolose (PNG o JPG) per il livello di zoom 10?
Dr.YSG

Puoi ottenere la forma delle tessere tile.osm.org(renderizzatore mapnik). Ad esempio http://tile.openstreetmap.org/10/590/329.png( zoom/ x/ y.png). Questi riquadri hanno Access-Control-Allow-Origin: *un'intestazione in modo da poterli ottenere da ajax o ottenere dati uri (base64) da canvas. È già possibile scaricare le piastrelle con il vostro manifest.json {id: 0-0-0}, ma è necessario assicurarsi che siano a destra zoom, x, ysequenza.
tbicr

1

Alcuni anni 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 un database). Quella soluzione potrebbe funzionare per te, anche se avrai bisogno di qualcuno che scriva l'applet e la firmi. Per le soluzioni di database, tale applet può utilizzare il jdbc disponibile per la maggior parte dei database utilizzando localhost su una porta adatta (ad esempio, 3306 per MySQL). Credo che il tag dell'applet sia deprecato in Html5 ma funziona ancora. Nessuna esperienza su tablet Android, quindi non posso commentare quella parte.


1
Ho iniziato a programmare in FORTRAN nel 1968 usando un card-punch. Quindi le soluzioni dell'età della pietra non sono nuove per me.
Dr.YSG
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.