Tengo una aplicación web sin conexión que usa appcaching. Necesito proporcionarle entre 10 MB y 20 MB de datos que guardará (del lado del cliente) que consisten principalmente en archivos de imagen PNG. El funcionamiento es el siguiente:
- Descargas e instalaciones de aplicaciones web en appcache (usa el manifiesto)
- Solicitudes de aplicaciones web desde archivos de datos PNG del servidor (¿cómo? - vea las alternativas a continuación)
- Ocasionalmente, la aplicación web se resincroniza con el servidor y realiza pequeñas actualizaciones / eliminaciones / adiciones parciales a la base de datos PNG
- FYI: el servidor es un servidor JSON REST, que puede colocar archivos en wwwroot para su recogida
Aquí está mi análisis actual de las "bases de datos" basadas en el cliente que manejan el almacenamiento de blobs binarios
VER ACTUALIZACIÓN en la parte inferior
- AppCache (a través del manifiesto, agregue todo el PNG y luego actualice a pedido)
- CONTRA: cualquier cambio de un elemento de la base de datos PNG significará la descarga completa de todos los elementos en el manifiesto (¡realmente malas noticias!)
- Almacenamiento web
- CON: Diseñado para almacenamiento JSON
- CON: solo puede almacenar blobs a través de la codificación base64 (probablemente un error fatal debido al costo de la decodificación)
- CONTRA: límite estricto de 5 MB para webStorage http://htmlui.com/blog/2011-08-23-5-obscure-facts-about-html5-localstorage.html
- PhoneGap y SQLLite
- CONTRA: el patrocinador la rechazará como una aplicación nativa que requiere certificación
- archivo zip
- El servidor crea un archivo zip, lo coloca en wwwroot y notifica al cliente
- el usuario tiene que descomprimir manualmente (al menos así es como lo veo) y guardar en el sistema de archivos del cliente
- La aplicación web usa FileSystem API para hacer referencia a archivos
- CON: ZIP puede ser demasiado grande (zip64?), Mucho tiempo para crear
- CONTRA: No estoy seguro de si la API de FileSystem siempre puede leer fuera de la caja de arena (eso creo)
- USB o tarjeta SD (de vuelta a la edad de piedra ...)
- El usuario será local en el servidor antes de desconectarse.
- Entonces podríamos hacer que inserte una tarjeta SD, dejar que el servidor la llene con archivos PNG
- Luego, el usuario lo conectará a la computadora portátil, tableta
- La aplicación web utilizará la API FileSystem para leer los archivos
- CONTRA: No estoy seguro de si la API de FileSystem siempre puede leer fuera de la caja de arena (eso creo)
- WebSQL
- CON: w3c lo ha abandonado (bastante mal)
- Podría considerar un contenedor de Javascript que usa IndexedDB y WebSQL como alternativa
- API FileSystem
- Chrome admite lectura / escritura de blobs
- CONTRA: no está claro acerca de IE y FireFox (IE10, tiene msSave no estándar)
- caniuse.com informa que es compatible con IOS y Android (pero, de nuevo, ¿es esto solo r / w de JSON o incluye la API de blob completa para escribir?
- CON: A la gente de FireFox no le gusta la API de FileSystem y no está claro si admiten guardar blobs: https://hacks.mozilla.org/2012/07/why-no-filesystem-api-in-firefox/
- PRO: mucho más rápido que IndexedDB para blobs según jsperf http://jsperf.com/indexeddb-vs-localstorage/15 (página 2)
- IndexedDB
- Buen soporte en IE10, FireFox (guardar, leer blobs)
- Buena velocidad y gestión más sencilla que un sistema de archivos (elimina, actualiza)
- PRO: consulte las pruebas de velocidad: http://jsperf.com/indexeddb-vs-localstorage/15
- Consulte este artículo sobre el almacenamiento y visualización de imágenes en IndexedDB: https://hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/
- CON: Confirmé que Chrome aún no admite la escritura de blobs (error actual, pero no está claro cuándo se solucionará)
- ACTUALIZACIÓN: ¡Los desarrolladores de Chrome confirman que están trabajando en esto tanto para escritorio como para Android! aún no hay una línea de tiempo.
- Contenedor de JavaScript de LawnChair http://brian.io/lawnchair/
- PRO: contenedor muy limpio para IndexedDB, WebSQL o cualquier base de datos que tenga (piense en polyfill)
- CONTRA: no se pueden almacenar blobs binarios, solo datos: uri (codificación base64) (probablemente falla fatal debido al costo de la decodificación)
- IndexedDB JQUERY polyFill https://github.com/axemclion/jquery-indexeddb
- Parashuram ha escrito un buen contenedor JQUERY para la interfaz sin procesar de IndexedDB
- PRO: simplifica enormemente el uso de IndexedDB, esperaba agregar un shim / polyfill para Chrome FileSystemAPI
- CON: Debería manejar blobs, pero no pude hacer que funcione
- idb.filesystem.js http://ericbidelman.tumblr.com/post/21649963613/idb-filesystem-js-bringing-the-html5-filesystem-api
- Eric Bidelman @ Google ha escrito un PolyFill the FileSystem API bien probado que usa Indexed DB como respaldo
- PRO: FileSystem API es ideal para almacenar blobs
- PRO: funciona muy bien en FireFox y Chrome
- PRO: ideal para sincronizar con CouchDB basado en la nube
- CON: no está claro por qué, pero no funciona en IE10
- Biblioteca JavaScript de PouchDB http://pouchdb.com/
- ideal para sincronizar un CouchDB con una base de datos local (usa WebSQL o IndexedDB (aunque no es mi problema)
- CON: SIN CONTRAS, PouchDB ahora admite blobs binarios para todos los navegadores recientes (IE, Chrome, Firefox, Chrome en dispositivos móviles, etc.), así como para muchos navegadores más antiguos. Ese no fue el caso cuando hice esta publicación por primera vez.
NOTA: para ver una codificación de datos: uri de PNG, creé un ejemplo en: http://jsbin.com/ivefak/1/edit
Funciones deseadas / útiles / innecesarias
- Sin aplicación nativa (EXE, PhoneGap, ObjectiveC, etc.) en el cliente (aplicación web pura)
- Solo necesita ejecutarse en los últimos Chrome, FireFox, IE10 para computadoras portátiles
- Quiero encarecidamente la misma solución para tabletas Android (IOS también sería bueno) pero solo necesita un navegador para funcionar (FF, Chrome, etc.)
- Población de base de datos inicial rápida
- REQUISITO: Recuperación muy rápida de imágenes por aplicación web desde el almacenamiento (DB, archivo)
- No destinado a los consumidores. Podemos restringir los navegadores y pedirle al usuario que realice tareas y configuraciones especiales, pero minimicemos eso
Implementaciones IndexedDB
- Hay un excelente artículo sobre cómo IE, FF y Chrome implementan esto internamente en: http://www.aaron-powell.com/web/indexeddb-storage
- En breve:
- IE usa el mismo formato de base de datos que Exchange y Active Directory para IndexedDB
- Firefox está usando SQLite, por lo que está implementando una base de datos NoSQL en la base de datos SQL
- Chrome (y WebKit) están utilizando una tienda Key / Value que tiene herencia en BigTable
Mis resultados actuales
- Elegí usar un enfoque IndexedDB (y polyfill con FileSystemAPI para Chrome hasta que envíen soporte para blob)
- Para buscar los mosaicos, tuve un dilema ya que la gente de JQUERY está ansiosa por agregar esto a AJAX
- Fui con XHR2-Lib de Phil Parsons, que es muy parecido a JQUERY .ajax () https://github.com/pmp/xhr2-lib
- Rendimiento para descargas de 100 MB (IE10 4s, Chrome 6s, FireFox 7s).
- No pude hacer que ninguno de los contenedores IndexedDB funcione para blobs (silla de jardín, PouchDB, jquery-indexeddb, etc.)
- Hice mi propia envoltura y el rendimiento es (IE10 2s, Chrome 3s, FireFox 10s)
- Con FF, supongo que estamos viendo el problema de rendimiento de usar una base de datos relacional (sqllite) para un almacenamiento que no es SQL.
- NOTA, Chrome tiene excelentes herramientas de depuración (pestaña de desarrollador, recursos) para inspeccionar el estado de IndexedDB.
Resultados FINALES publicados a continuación como respuesta
Actualizar
PouchDB ahora admite blobs binarios para todos los navegadores recientes (IE, Chrome, Firefox, Chrome en dispositivos móviles, etc.), así como para muchos navegadores más antiguos. Ese no fue el caso cuando hice esta publicación por primera vez.
Respuestas:
Resultados Caché de blobs sin conexión para mapas deslizantes PNG
Pruebas
Obtener del servidor web
Almacenamiento
Monitor
Resultados
fuente
Para sus requisitos, sugiero que desarrolle un nuevo polyfill basado en otros dos: API FileSystem para IndexedDB e IndexedDB para WebSQL , es la mejor opción.
El primero permitirá el soporte para almacenar blobs en Chrome (FileSystem API) y Firefox (IndexedDB), mientras que el segundo debería proporcionar el soporte para Android e iOS ( WebSQL ). Lo que se necesita es hacer que estos polyfills funcionen juntos, y supongo que no es difícil.
NB: Dado que no pude encontrar ninguna información en la web sobre esto, debe probar si el almacenamiento de blobs con el polyfill de WebSQL funcionará en iOS y Android. Sin embargo, parece que debería funcionar:
Fuente
fuente
Tengo ejemplos de almacenamiento en caché de mapas (ejemplo abierto, descubrir regiones y zooms, desconectar y las regiones descubiertas estarán disponibles).
Hay
map.js
- capa de mapa para mosaicos fuera de línea,storage.js
- implementación de almacenamiento basada en IndexedDb y WebSQL (pero esto solo prueba la implementación con bajo rendimiento).Información adicional sobre tamaños para 2 mil millones de ciudades ( Minsk ):
fuente
PNG
con la proyección predeterminada (EGPS: 3857) pero no importaJPEG
oPNG
porque se usó porimg
etiqueta ocanvas
. Con mi ejemplo, puede precargar mosaicos si conoce las claves de mosaicos (storage.add('x_y_z', 'data:image/png;base64,...')
para cada mosaico almacenado), pero siempre puede obtenerlos si solo conoce los límites (polígono) y los zooms.tile.osm.org
(renderizador de mapnik). Por ejemplohttp://tile.openstreetmap.org/10/590/329.png
(zoom
/x
/y
.png). Estos mosaicos tienenAccess-Control-Allow-Origin: *
encabezado para que pueda obtenerlos por ajax u obtener datos uri (base64) por lienzo. Ya se puede descargar baldosas con sumanifest.json
{id: 0-0-0}
, pero hay que ver si dispone de la derechazoom
,x
,y
secuencia.Hace unos años (no exactamente la edad de piedra), estaba usando un subprograma java firmado que consultaba a su servidor los requisitos de sincronización / actualización, descargaba los archivos apropiados del servidor y los guardaba en el sistema de archivos del usuario (no en una base de datos). Esa solución podría funcionar para usted, aunque necesitará que alguien escriba el subprograma y lo firme. Para soluciones de bases de datos, un subprograma de este tipo puede usar el jdbc disponible para la mayoría de las bases de datos usando localhost en un puerto adecuado (por ejemplo, 3306 para MySQL). Creo que la etiqueta del subprograma está obsoleta en Html5, pero aún funciona. No tengo experiencia en tabletas Android, así que no puedo comentar sobre esa parte.
fuente